ProcessRequestClass.php 5.71 KB
<?php
/**
 * @class ProcessRequestClass
 * @brief Implementation of a RequestAbstractClass for process request
 * @details
 */
class ProcessRequestClass extends RequestAbstractClass
{
	/*
	 * @brief Init a process request of type "run"
	*/
	private function initRun()
	{
		if ($this->requestData->getCmd() == '')
		{
			$this->requestData->setLastErrorMessage('No process command defined');
			return false;
		}

		if ($this->requestData->getWorkingPath() == '')
		{
			$this->requestData->setLastErrorMessage('No working path defined');
			return false;
		}

		if (!is_dir($this->requestData->getWorkingPath()))
		{
			if (!mkdir($this->requestData->getWorkingPath(),0777) || !is_dir($this->requestData->getWorkingPath()))
			{
				$this->requestData->setLastErrorMessage('Cannot create working dir');
				return false;
			}
		}

		$this->requestData->setGetErrorMsgCmd(KernelConfigClass::getKernelBinPath()."amdaGetErrorMsg \$ERROR_CODE");

		return true;
	}

	/*
	 * @brief Init a process request of type "delete" or "info"
	*/
	private function initDeleteOrInfo()
	{
		if ($this->requestData->getId() == "")
		{
			$this->requestData->setLastErrorMessage('No process id defined');
			return false;
		}
		return true;
	}

	/*
	 * @brief Init a process request
	*/
	public function init()
	{
		if (!isset($this->requestData))
			return false;

		$this->requestData->setSuccess(false);
		$this->requestData->setLastErrorMessage('Cannot init process request');

		switch ($this->requestData->getType())
		{
			case ProcessTypeEnumClass::RUN :
				return $this->initRun();
			case ProcessTypeEnumClass::DELETE :
			case ProcessTypeEnumClass::INFO :
				return $this->initDeleteOrInfo();
		}

		return false;
	}

	/*
	 * @brief Update data from process info
	*/
	private function updateProcess($processInfo, $processMgr)
	{
		$this->requestData->setRunningPath($processInfo['runningpath']);

		$this->requestData->setId($processInfo['id']);
		if ($processInfo['isrunning'])
			$this->requestData->setStatus(ProcessStatusEnumClass::RUNNING);
		else
		{
			if (isset($processInfo['iskilled']) && $processInfo['iskilled'])
				$this->requestData->setStatus(ProcessStatusEnumClass::KILLED);
			else if (!isset($processInfo['exitcode']) || ($processInfo['exitcode'] != 0))
				$this->requestData->setStatus(ProcessStatusEnumClass::ERROR);
			else
				$this->requestData->setStatus(ProcessStatusEnumClass::DONE);
			$this->requestData->setErrorCode($processInfo['exitcode']);
			if (!empty($processInfo['exitcode'])) {
				$this->requestData->setErrorMsg($processInfo['errormsg']);
			} 
			$this->requestData->setExecTime($processInfo['exectime']);
			$processMgr->deleteProcess($processInfo['id']);
		}

		$this->requestData->setStart($processInfo['runningstart']);
	}

	/*
	 *
	 */
	private function serverReady($processMgr, $user)
	{
		if (!empty($user) && !$this->requestData->getFromWS()) {
			// Check nb running processes for the current user
			$result = $processMgr->getNbRunningProcesses($user);
			if (!$result['success']) {
				return $result;
			}
			if ($result['result']['nb'] >= KernelConfigClass::getNbMaxProcessByUser()) {
				return array(
					'success' => FALSE,
					'message' => 'You exceed the maximum number of processes allowed by user. Please wait the end of some jobs.',
				);
			}
		}
		// Check nb running processes for all users
		$result = $processMgr->getNbRunningProcesses();
		if (!$result['success']) {
			return $result;
		}
		if ($result['result']['nb'] >= KernelConfigClass::getNbMaxProcessGlobal()) {
			return array(
				'success' => FALSE,
				'message' => 'Our server is busy. Please re run your request later.',
			);
		}
		return array(
			'success' => TRUE,
		);
	}

	/*
	 * @brief Run a process request
	*/
	public function run()
	{
		if (!isset($this->requestData))
			return false;

		$this->requestData->setSuccess(false);
		$this->requestData->setLastErrorMessage('Cannot run process request');

		//create the process manager
		$processMgr = new ProcessManagerClass($this->requestData->getManagerFilePath());

		$return_code = FALSE;
		switch ($this->requestData->getType())
		{
			case ProcessTypeEnumClass::RUN :
				$result = $this->serverReady($processMgr, $this->requestData->getUser());
				if ($result['success']) {
					//run process
					$result = $processMgr->runProcess(
					$this->requestData->getCmd(),
					$this->requestData->getWorkingPath(),
					$this->requestData->getEnvVars(),
					$this->requestData->getPostCmd(),
					$this->requestData->getGetErrorMsgCmd(),
					$this->requestData->getBatchEnable(),
					$this->requestData->getUser(),
					$this->requestData->getFromWS());
					if ($result['success']) {
						$return_code = TRUE;
						$this->updateProcess($result['result'], $processMgr);
					}
				}
				break;
			case ProcessTypeEnumClass::DELETE :
				//delete process
				$result = $processMgr->deleteProcess($this->requestData->getId());
				if ($result['success']) {
					$return_code = TRUE;
					$result = $result['result'];
				}
				break;
			case ProcessTypeEnumClass::INFO :
				//get process info
				$result = $processMgr->getProcessInfo($this->requestData->getId(),true);
				if ($result['success'])
					$this->updateProcess($result['result'], $processMgr);
				$return_code = TRUE; //Return TRUE even if the process cannot be retrieved
				break;
			case ProcessTypeEnumClass::KILL :
				$result = $processMgr->killProcess($this->requestData->getId());
				if ($result['success']) {
					$return_code = TRUE;
					$result = $result['result'];
				}
				break;
			default :
				$this->requestData->setLastErrorMessage("Process method not implemented");
				return false;
		}

		$this->requestData->setSuccess($result['success']);

		if (!$result['success'])
			$this->requestData->setLastErrorMessage($result['message']);

		return $return_code;
	}
}
?>