ProcessClass.php 4.59 KB
<?php
/**
 * @class ProcessClass
 * @brief Definition of a process
 * @details
 */
class ProcessClass
{
	private $command;
	private $postProcessCmd;

	private $outputFile;
	private $exitCodeFile;
	private $processFile;

	private $pID;
	private $runningPath;
	private $runningStart;

	/*
	 * @brief Constructor
	*/
	function __construct($command, $postProcessCmd = "")
	{
		$this->command        = $command;
		$this->postProcessCmd = $postProcessCmd;
		$this->pID            = 0;
	}

	/*
	 * @brief Init an existing process
	*/
	public function init($outputFile, $exitCodeFile, $processFile, $pid, $runningPath, $runningStart)
	{
		$this->outputFile   = $outputFile;
		$this->exitCodeFile = $exitCodeFile;
		$this->processFile  = $processFile;
		$this->pID          = $pid;
		$this->runningPath  = $runningPath;
		$this->runningStart = $runningStart;
	}

	/*
	 * @brief Get the command of the process
	*/
	public function getCommand()
	{
		return $this->command;
	}

	/*
	 * @brief Get the output file of the process
	*/
	public function getOutputFile()
	{
		return $this->outputFile;
	}

	/*
	 * @brief Get the exit code file of a process
	*/
	public function getExitCodeFile()
	{
		return $this->exitCodeFile;
	}

	/*
	 * @brief Get the process file
	*/
	public function getProcessFile()
	{
		return $this->processFile;
	}

	/*
	 * @brief Get the running path of the request
	*/
	public function getRunningPath()
	{
		return $this->runningPath;
	}

	/*
	 * @brief Get the start date of a process
	*/
	public function getRunningStart()
	{
		return $this->runningStart;
	}

	/*
	 * @brief Get the exit code of the process
	*/
	public function getExitCode()
	{
		if ($this->pID == 0)
			return -1000;
		if ($this->isRunning())
			return -1001;
		if (!chdir($this->runningPath))
			return -1002;
		if (!file_exists($this->exitCodeFile))
			return -1003;
		$result = file_get_contents($this->exitCodeFile);

		if ($result === false)
			return -1004;

		return intval($result);
	}

	/*
	 * @brief Get the PID of the process
	*/
	public function getPID()
	{
		return $this->pID;
	}

	/*
	 * @brief Run the process
	*/
	public function run($runningPath, $envArray)
	{
		if ($this->isRunning())
			return false;

		if (!is_dir($runningPath))
			return false;

		$this->runningPath = $runningPath;

		if (!$this->initRun($envArray))
			return false;

		$cmd = 'nohup ./'.$this->processFile.' > /dev/null 2>&1 & echo $!';
		exec($cmd,$op);
		$this->pID = (int)$op[0];
		$this->runningStart = time();

		return ($this->pID > 0);
	}

	/*
	 * @brief Wait end of the process execution
	*/
	public function waitEndOfProcess($callback, $batchEnabled)
	{
		while ($this->isRunning())
		{
			if (!call_user_func($callback,$this,$batchEnabled))
				return false;
			sleep(2);
		}
		return true;
	}

	/*
	 * @brief Test if the process is running
	*/
	public function isRunning()
	{
		if ($this->pID == 0)
			return false;
		$cmd = 'ps -p '.$this->pID;
		exec($cmd,$op);
		return isset($op[1]);
	}

	/*
	 * @brief Stop the process execution
	*/
	public function stop()
	{
		//Kill process and all child processes
		$cmd = "pkill -TERM -P $this->pID";
		//$cmd = 'kill '.$this->pID;
		exec($cmd);
		return !$this->isRunning();
	}

	/*
	 * @brief Delete the process
	*/
	public function delete()
	{
		if (!$this->stop())
			return false;

		if (!chdir($this->runningPath))
			return false;
		 
		if (file_exists($this->outputFile))
			unlink($this->outputFile);

		if (file_exists($this->exitCodeFile))
			unlink($this->exitCodeFile);

		if (file_exists($this->processFile))
			unlink($this->processFile);
		 
		return true;
	}

	/*
	 * @brief Init the execution of a process
	*/
	private function initRun($envArray)
	{
		if($this->isRunning())
			return false;

		if (!chdir($this->runningPath))
			return false;

		$this->outputFile   = "cmd_output";
		$this->exitCodeFile = "cmd_exitcode";
		$this->processFile  = "cmd_process";

		if (file_exists($this->outputFile))
			unlink($this->outputFile);

		if (file_exists($this->exitCodeFile))
			unlink($this->exitCodeFile);

		if (file_exists($this->processFile))
			unlink($this->processFile);

		file_put_contents($this->processFile, "#!/bin/bash".PHP_EOL);
		foreach ($envArray as $key => $value)
			file_put_contents($this->processFile,"export ".$key."=".$value.PHP_EOL, FILE_APPEND);
		file_put_contents($this->processFile, $this->command." > ".$this->outputFile." 2>&1".PHP_EOL, FILE_APPEND);
		file_put_contents($this->processFile, "echo $? > ".$this->exitCodeFile.PHP_EOL, FILE_APPEND);
		if ($this->postProcessCmd != "")
			file_put_contents($this->processFile, $this->postProcessCmd.PHP_EOL, FILE_APPEND);

		chmod($this->processFile, 0755);

		return true;
	}
}

?>