Commit 5210c93fc2ce90b494ca52ef3b4e10e58f675f3c

Authored by Benjamin Renard
2 parents 53fc468c 1903e7e0

Merge master

src/InputOutput/IHMImpl/Params/IHMInputOutputParamsAbstractClass.php
... ... @@ -161,6 +161,7 @@ abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
161 161 $deleteData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
162 162 $deleteData->setType(ProcessTypeEnumClass::DELETE);
163 163 $deleteData->setId($jobId);
  164 + $deleteData->setUser(IHMConfigClass::getUserName());
164 165  
165 166 $processRequest = new ProcessRequestClass();
166 167 $processRequest->setData($deleteData);
... ... @@ -219,6 +220,7 @@ abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
219 220 $this->paramsData->setLocalBasePath(IHMConfigClass::getLocalBasePath());
220 221 $this->paramsData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
221 222 $this->paramsData->setTask($this->getTask($input));
  223 + $this->paramsData->setUser(IHMConfigClass::getUserName());
222 224 $this->input = $input;
223 225  
224 226 return $this->unmarshallRequest($input);
... ...
src/InputOutput/IHMImpl/Process/IHMInputOutputCleanProcessClass.php
... ... @@ -43,6 +43,7 @@ class IHMInputOutputCleanProcessClass implements InputOutputInterface
43 43 $processData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
44 44 $processData->setType(ProcessTypeEnumClass::DELETE);
45 45 $processData->setId($jobid);
  46 + $processData->setUser(IHMConfigClass::getUserName());
46 47  
47 48 $this->processDatas[] = $processData;
48 49 }
... ... @@ -69,4 +70,4 @@ class IHMInputOutputCleanProcessClass implements InputOutputInterface
69 70 }
70 71 }
71 72  
72   -?>
73 73 \ No newline at end of file
  74 +?>
... ...
src/InputOutput/IHMImpl/Process/IHMInputOutputDeleteProcessClass.php
... ... @@ -32,6 +32,7 @@ class IHMInputOutputDeleteProcessClass implements InputOutputInterface
32 32 $this->paramsData->setType(ProcessTypeEnumClass::DELETE);
33 33  
34 34 $this->paramsData->setId($input->id);
  35 + $this->paramsData->setUser(IHMConfigClass::getUserName());
35 36  
36 37 return $this->paramsData;
37 38 }
... ... @@ -63,4 +64,4 @@ class IHMInputOutputDeleteProcessClass implements InputOutputInterface
63 64 }
64 65 }
65 66  
66   -?>
67 67 \ No newline at end of file
  68 +?>
... ...
src/InputOutput/IHMImpl/Process/IHMInputOutputGetInfoProcessClass.php
... ... @@ -32,6 +32,7 @@ class IHMInputOutputGetInfoProcessClass implements InputOutputInterface
32 32 $this->paramsData->setType(ProcessTypeEnumClass::INFO);
33 33  
34 34 $this->paramsData->setId($input);
  35 + $this->setUser(IHMConfigClass::getUserName());
35 36  
36 37 return $this->paramsData;
37 38 }
... ...
src/InputOutput/IHMImpl/Process/IHMInputOutputInfoProcessAbstractClass.php
... ... @@ -35,6 +35,7 @@ abstract class IHMInputOutputInfoProcessAbstractClass implements InputOutputInte
35 35 $processData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
36 36 $processData->setType(ProcessTypeEnumClass::INFO);
37 37 $processData->setId($jobid);
  38 + $processData->setUser(IHMConfigClass::getUserName());
38 39  
39 40 $this->processDatas[] = $processData;
40 41 }
... ... @@ -61,4 +62,4 @@ abstract class IHMInputOutputInfoProcessAbstractClass implements InputOutputInte
61 62 abstract protected function marshallResult($data);
62 63 }
63 64  
64   -?>
65 65 \ No newline at end of file
  66 +?>
... ...
src/Request/Config/KernelConfigClass.php
... ... @@ -26,6 +26,9 @@ class KernelConfigClass
26 26  
27 27 private static $defaultGapThreshold = "5";
28 28  
  29 + private static $nbMaxProcessByUser = 10;
  30 + private static $nbMaxProcessGlobal = 100;
  31 +
29 32  
30 33 private static $userHost = "";
31 34 private static $userName = "";
... ... @@ -173,6 +176,16 @@ class KernelConfigClass
173 176 return self::$timeToBatchMode;
174 177 }
175 178  
  179 + public static function getNbMaxProcessByUser()
  180 + {
  181 + return self::$nbMaxProcessByUser;
  182 + }
  183 +
  184 + public static function getNbMaxProcessGlobal()
  185 + {
  186 + return self::$nbMaxProcessGlobal;
  187 + }
  188 +
176 189 public static function write($working_dir, $compilation_path = "", $localbase_path = "", $functionsfile_path = "", $constantsfile_path = "", $paramtemplatesfile_path = "")
177 190 {
178 191 //create app.properties file
... ...
src/Request/ParamsRequestImpl/ParamsRequestClass.php
... ... @@ -232,11 +232,10 @@ class ParamsRequestClass extends ProcessRequestClass
232 232 */
233 233 public function run()
234 234 {
235   - $amdaStat = new AmdaStats(IHMConfigClass::getUserName());
236   -
237   - $task = $this->requestData->getTask();
238   - if (isset($task) && (count($this->requestData->getDatasetForStat()) > 0))
239   - $amdaStat->addTask(IHMConfigClass::getUserName(), $task, $this->requestData->getDatasetForStat());
  235 + $amdaStat = new AmdaStats($this->requestData->getUser());
  236 +
  237 + if (count($this->requestData->getDatasetForStat()) > 0)
  238 + $amdaStat->addTask(IHMConfigClass::getUserName(), $this->requestData->getTask(), $this->requestData->getDatasetForStat());
240 239  
241 240 return parent::run();
242 241 }
... ...
src/Request/ProcessRequestImpl/Process/ProcessClass.php
... ... @@ -20,17 +20,19 @@ class ProcessClass
20 20 private $runningPath;
21 21 private $runningStart;
22 22 private $fromWS;
  23 + private $user;
23 24  
24 25 /*
25 26 * @brief Constructor
26 27 */
27   - function __construct($command, $postProcessCmd = "", $getErrorMsgCmd = "", $fromWS = FALSE)
  28 + function __construct($command, $postProcessCmd = "", $getErrorMsgCmd = "", $user = "", $fromWS = FALSE)
28 29 {
29 30 $this->command = $command;
30 31 $this->postProcessCmd = $postProcessCmd;
31 32 $this->getErrorMsgCmd = $getErrorMsgCmd;
32 33 $this->pID = 0;
33 34 $this->fromWS = $fromWS;
  35 + $this->user = $user;
34 36 }
35 37  
36 38 /*
... ... @@ -197,6 +199,14 @@ class ProcessClass
197 199 }
198 200  
199 201 /*
  202 + * @brief Get user that run the request. Empty if not known.
  203 + */
  204 + public function getUser()
  205 + {
  206 + return $this->user;
  207 + }
  208 +
  209 + /*
200 210 * @brief Run the process
201 211 */
202 212 public function run($runningPath, $envArray)
... ...
src/Request/ProcessRequestImpl/Process/ProcessManagerClass.php
... ... @@ -19,9 +19,9 @@ class ProcessManagerClass
19 19 /*
20 20 * @brief Run a process
21 21 */
22   - public function runProcess($cmd, $runningPath, $envArray, $postProcessCmd, $getErrorMsgCmd, $batchEnabled, $fromWS = FALSE)
  22 + public function runProcess($cmd, $runningPath, $envArray, $postProcessCmd, $getErrorMsgCmd, $batchEnabled, $user, $fromWS = FALSE)
23 23 {
24   - $process = new ProcessClass($cmd, $postProcessCmd, $getErrorMsgCmd, $fromWS);
  24 + $process = new ProcessClass($cmd, $postProcessCmd, $getErrorMsgCmd, $user, $fromWS);
25 25  
26 26 if (!$process->run($runningPath, $envArray))
27 27 return array("success" => false, "message" => "Cannot run the process");
... ... @@ -85,6 +85,14 @@ class ProcessManagerClass
85 85 return true;
86 86 }
87 87  
  88 + /*
  89 + * @brief Get nb of running processes. Is $name is not empty, get only the nb for the specifier user.
  90 + */
  91 + public function getNbRunningProcesses($user = "") {
  92 + $res = $this->concurrentAccessProcessManagerFile(array($this,'getRunningProcessesNb'),$user);
  93 + return $res;
  94 + }
  95 +
88 96 /*
89 97 * @brief Add a process in the manager file
90 98 */
... ... @@ -123,8 +131,10 @@ class ProcessManagerClass
123 131 $dom->preserveWhiteSpace = false;
124 132 $dom->formatOutput = true;
125 133 $res = $dom->load($this->processManagerFilePath);
126   - if ($res)
  134 + if ($res) {
  135 + $this->cleanupProcessManagerFile($dom);
127 136 $func_res = call_user_func($callback,$dom,$additionalParams);
  137 + }
128 138 }
129 139 }
130 140 else
... ... @@ -151,6 +161,28 @@ class ProcessManagerClass
151 161 }
152 162  
153 163 /*
  164 + * @brief Method used to be sure that the process file is always clean
  165 + */
  166 + private function cleanupProcessManagerFile($dom) {
  167 + $processNodes = $dom->documentElement->getElementsByTagName("process");
  168 + $processNode = $processNodes->item(0);
  169 + $to_remove = array();
  170 + while ($processNode)
  171 + {
  172 + $pathNodes = $processNode->getElementsByTagName("runningpath");
  173 + if (($pathNodes->length == 0) || empty($pathNodes->item(0)->nodeValue) ||
  174 + (!is_dir($pathNodes->item(0)->nodeValue))) {
  175 + $to_remove[] = $processNode;
  176 + }
  177 + $processNode = $this->fNextEltSibling($processNode);
  178 + }
  179 + foreach ($to_remove as $processNode) {
  180 + $dom->documentElement->removeChild($processNode);
  181 + }
  182 + $dom->save($this->processManagerFilePath);
  183 + }
  184 +
  185 + /*
154 186 * @brief Update process info if a node of the manager file
155 187 */
156 188 private function updateProcessInProcessNode($dom, $processNode, $process) {
... ... @@ -168,6 +200,7 @@ class ProcessManagerClass
168 200 $this->updateProcessStatusToNode($dom,$processNode,"runningstart",$process->getRunningStart());
169 201 $this->updateProcessStatusToNode($dom,$processNode,"isrunning",$process->isRunning() ? "true" : "false");
170 202 $this->updateProcessStatusToNode($dom,$processNode,"lastupdate",time());
  203 + $this->updateProcessStatusToNode($dom,$processNode,"user", $process->getUser());
171 204 $this->updateProcessStatusToNode($dom,$processNode,"fromws", $process->getFromWS() ? "true" : "false");
172 205 }
173 206  
... ... @@ -193,6 +226,7 @@ class ProcessManagerClass
193 226 "isrunning" => ($this->getNodeValueFromNode($processNode, "isrunning") == "true"),
194 227 "iskilled" => ($this->getNodeValueFromNode($processNode, "iskilled") == "true"),
195 228 "lastupdate" => $this->getNodeValueFromNode($processNode, "lastupdate"),
  229 + "user" => $this->getNodeValueFromNode($processNode, "user"),
196 230 "fromws" => ($this->getNodeValueFromNode($processNode, "fromws") == "true"),
197 231 );
198 232 }
... ... @@ -360,6 +394,37 @@ class ProcessManagerClass
360 394  
361 395 return array('success' => false, 'message' => 'Cannot kill process from id '.$id);
362 396 }
  397 +
  398 + /*
  399 + * @brief Get nb of running processes. Is $name is not empty, get only the nb for the specifier user.
  400 + */
  401 + private function getRunningProcessesNb($dom, $user)
  402 + {
  403 + $processNodes = $dom->documentElement->getElementsByTagName("process");
  404 + $processNode = $processNodes->item(0);
  405 + $nb = 0;
  406 + while ($processNode)
  407 + {
  408 + $isRunningNodes = $processNode->getElementsByTagName("isrunning");
  409 + if (($isRunningNodes->length == 0) || empty($isRunningNodes->item(0)->nodeValue) ||
  410 + ($isRunningNodes->item(0)->nodeValue != "true")) {
  411 + $processNode = $this->fNextEltSibling($processNode);
  412 + continue;
  413 + }
  414 + if (!empty($user)) {
  415 + $userNodes = $processNode->getElementsByTagName("user");
  416 + if (($userNodes->length == 0) || empty($userNodes->item(0)->nodeValue) ||
  417 + ($userNodes->item(0)->nodeValue != $user)) {
  418 + $processNode = $this->fNextEltSibling($processNode);
  419 + continue;
  420 + }
  421 + }
  422 + ++$nb;
  423 + $processNode = $this->fNextEltSibling($processNode);
  424 + }
  425 +
  426 + return array('success' => true, 'nb' => $nb);
  427 + }
363 428 }
364 429  
365 430 ?>
... ...
src/Request/ProcessRequestImpl/ProcessRequestClass.php
... ... @@ -103,6 +103,40 @@ class ProcessRequestClass extends RequestAbstractClass
103 103 }
104 104  
105 105 /*
  106 + *
  107 + */
  108 + private function serverReady($processMgr, $user)
  109 + {
  110 + if (!empty($user) && !$this->requestData->getFromWS()) {
  111 + // Check nb running processes for the current user
  112 + $result = $processMgr->getNbRunningProcesses($user);
  113 + if (!$result['success']) {
  114 + return $result;
  115 + }
  116 + if ($result['result']['nb'] >= KernelConfigClass::getNbMaxProcessByUser()) {
  117 + return array(
  118 + 'success' => FALSE,
  119 + 'message' => 'You exceed the maximum number of processes allowed by user. Please wait the end of some jobs.',
  120 + );
  121 + }
  122 + }
  123 + // Check nb running processes for all users
  124 + $result = $processMgr->getNbRunningProcesses();
  125 + if (!$result['success']) {
  126 + return $result;
  127 + }
  128 + if ($result['result']['nb'] >= KernelConfigClass::getNbMaxProcessGlobal()) {
  129 + return array(
  130 + 'success' => FALSE,
  131 + 'message' => 'Our server is busy. Please re run your request later.',
  132 + );
  133 + }
  134 + return array(
  135 + 'success' => TRUE,
  136 + );
  137 + }
  138 +
  139 + /*
106 140 * @brief Run a process request
107 141 */
108 142 public function run()
... ... @@ -120,18 +154,22 @@ class ProcessRequestClass extends RequestAbstractClass
120 154 switch ($this->requestData->getType())
121 155 {
122 156 case ProcessTypeEnumClass::RUN :
123   - //run process
124   - $result = $processMgr->runProcess(
125   - $this->requestData->getCmd(),
126   - $this->requestData->getWorkingPath(),
127   - $this->requestData->getEnvVars(),
128   - $this->requestData->getPostCmd(),
129   - $this->requestData->getGetErrorMsgCmd(),
130   - $this->requestData->getBatchEnable(),
131   - $this->requestData->getFromWS());
  157 + $result = $this->serverReady($processMgr, $this->requestData->getUser());
132 158 if ($result['success']) {
133   - $return_code = TRUE;
134   - $this->updateProcess($result['result'], $processMgr);
  159 + //run process
  160 + $result = $processMgr->runProcess(
  161 + $this->requestData->getCmd(),
  162 + $this->requestData->getWorkingPath(),
  163 + $this->requestData->getEnvVars(),
  164 + $this->requestData->getPostCmd(),
  165 + $this->requestData->getGetErrorMsgCmd(),
  166 + $this->requestData->getBatchEnable(),
  167 + $this->requestData->getUser(),
  168 + $this->requestData->getFromWS());
  169 + if ($result['success']) {
  170 + $return_code = TRUE;
  171 + $this->updateProcess($result['result'], $processMgr);
  172 + }
135 173 }
136 174 break;
137 175 case ProcessTypeEnumClass::DELETE :
... ...
src/Request/ProcessRequestImpl/ProcessRequestDataClass.php
... ... @@ -51,6 +51,7 @@ class ProcessRequestDataClass extends RequestDataClass
51 51 private $start = 0;
52 52 private $runningPath = "";
53 53 private $fromWS = false;
  54 + private $user = "";
54 55  
55 56 public function getManagerFilePath()
56 57 {
... ... @@ -211,6 +212,16 @@ class ProcessRequestDataClass extends RequestDataClass
211 212 {
212 213 $this->fromWS = $fromWS;
213 214 }
  215 +
  216 + public function getUser()
  217 + {
  218 + return $this->user;
  219 + }
  220 +
  221 + public function setUser($user)
  222 + {
  223 + $this->user = $user;
  224 + }
214 225 }
215 226  
216 227 ?>
... ...