Commit 131e60ff86b0665d289144346547141cad7908c6

Authored by Benjamin Renard
1 parent 2c928626

Implement real concurrent access for jobs manager + improve WS jobs manager + re…

…move some warning messages
src/InputOutput/IHMImpl/Params/IHMInputOutputParamsAbstractClass.php
... ... @@ -52,6 +52,14 @@ abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
52 52 }
53 53  
54 54 /*
  55 + * @brief Get Task
  56 + */
  57 + protected function getTask($input)
  58 + {
  59 + return $input->nodeType;
  60 + }
  61 +
  62 + /*
55 63 * @brief Unmarshall the time definition from the IHM request
56 64 */
57 65 protected function unmarshallTimeDefinition($input, $requestIndex, $ttFileIndex = -1, $ttIntIndex = -1)
... ... @@ -210,7 +218,7 @@ abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
210 218 $this->paramsData->setCompilationPath(IHMConfigClass::getCompilationPath());
211 219 $this->paramsData->setLocalBasePath(IHMConfigClass::getLocalBasePath());
212 220 $this->paramsData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
213   - $this->paramsData->setTask($input->nodeType);
  221 + $this->paramsData->setTask($this->getTask($input));
214 222 $this->input = $input;
215 223  
216 224 return $this->unmarshallRequest($input);
... ...
src/InputOutput/IHMImpl/Tools/IHMJobsManagerClass.php
... ... @@ -5,8 +5,7 @@
5 5 * @details
6 6 */
7 7 class IHMJobsManagerClass {
8   -
9   - protected $jobXml, $jobXmlName;
  8 + protected $isWSJob = false;
10 9  
11 10 protected $bkgRootNode = array('condition' => 'bkgSearch-treeRootNode',
12 11 'request' => 'bkgPlot-treeRootNode',
... ... @@ -26,27 +25,149 @@ class IHMJobsManagerClass {
26 25 }
27 26  
28 27 /*
29   - * @brief Load jobs file and create it if needed
30   - */
31   - protected function init()
  28 + * @brief Get path to the jobs file
  29 + */
  30 + protected function getJobsFilePath()
  31 + {
  32 + return IHMConfigClass::getUserJobsFile();
  33 + }
  34 +
  35 + /*
  36 + * @bried Send an error notification
  37 + */
  38 + protected function sendErrorNotification($message) {
  39 + // Nothing to do here
  40 + // It used to send an email with WS
  41 + }
  42 +
  43 + /*
  44 + * @brief Decode a request object file
  45 + */
  46 + public function getRequestObjectFile($id)
  47 + {
  48 + if (!file_exists($this->getRequestObjectFilePath($id)))
  49 + return NULL;
  50 + return json_decode(file_get_contents($this->getRequestObjectFilePath($id)));
  51 + }
  52 +
  53 + /*
  54 + * @brief delete a job
  55 + */
  56 + public function deleteJob($id)
  57 + {
  58 + return $this->concurrentAccessJobsFile(array($this,'deleteJobFromId'),$id);
  59 + }
  60 +
  61 + /*
  62 + * @brief get job info about a job
  63 + */
  64 + public function getJobInfo($id)
  65 + {
  66 + return $this->concurrentAccessJobsFile(array($this,'getJobInfoById'),$id);
  67 + }
  68 +
  69 + /*
  70 + * @brief Add a new job
  71 + */
  72 + public function addJob($obj, $id, $folder, $running, $start, $result, $exitcode, $exectime = 0)
  73 + {
  74 + return $this->concurrentAccessJobsFile(array($this,'addNewJob'), array(
  75 + 'obj' => $obj,
  76 + 'id' => $id,
  77 + 'folder' => $folder,
  78 + 'running' => $running,
  79 + 'start' => $start,
  80 + 'result' => $result,
  81 + 'exitcode' => $exitcode,
  82 + 'exectime' => $exectime,
  83 + ));
  84 + }
  85 +
  86 + /*
  87 + * @brief Update the status of a job
  88 + */
  89 + public function updateJobStatus($id, $running, $exitcode, $exectime = 0)
32 90 {
33   - $this->jobXmlName = IHMConfigClass::getUserJobsFile();
34   - $this->jobXml = new DomDocument("1.0");
  91 + return $this->concurrentAccessJobsFile(array($this,'updateJobStatusById'), array(
  92 + 'id' => $id,
  93 + 'running' => $running,
  94 + 'exitcode' => $exitcode,
  95 + 'exectime' => $exectime,
  96 + ));
  97 + }
35 98  
36   - if (!file_exists($this->jobXmlName))
  99 + /*
  100 + * @brief Get the list of jobs with a specific status
  101 + */
  102 + public function getJobsByStatus($status)
  103 + {
  104 + return $this->concurrentAccessJobsFile(array($this,'getJobsByStatusInDom'), $status);
  105 + }
  106 +
  107 + /*
  108 + * @brief Get jobs that use a specific working dir
  109 + */
  110 + public function getJobsByWorkingDir($folder)
  111 + {
  112 + return $this->concurrentAccessJobsFile(array($this,'getJobsByWorkingDirInDom'), $folder);
  113 + }
  114 +
  115 + /*
  116 + * @brief Get all jobs to clean (immediate result jobs)
  117 + */
  118 + public function getJobsToClean()
  119 + {
  120 + return $this->concurrentAccessJobsFile(array($this,'getJobsToCleanInDom'), array());
  121 + }
  122 +
  123 + /*
  124 + *
  125 + */
  126 + protected function concurrentAccessJobsFile($callback, $additionalParams)
  127 + {
  128 + $lockFile = $this->getJobsFilePath().".lockfile";
  129 +
  130 + $fp = fopen($lockFile, "w+");
  131 +
  132 + if ($fp === false) {
  133 + $this->sendErrorNotification('Cannot open jobs manager lock file');
  134 + return array('success' => false, 'message' => 'Cannot open jobs manager lock file');
  135 + }
  136 +
  137 + $res = true;
  138 +
  139 + if (flock($fp, LOCK_EX))
37 140 {
38   - $res = $this->createJobsFile();
39   - if (!$res['success'])
40   - return $res;
  141 + if (!file_exists($this->getJobsFilePath())) {
  142 + $res = $this->createJobsFile();
  143 + if (!$res) {
  144 + $this->sendErrorNotification('Cannot create '.$this->getJobsFilePath());
  145 + }
  146 + }
  147 + if ($res)
  148 + {
  149 + $dom = new DOMDocument("1.0","UTF-8");
  150 + $dom->preserveWhiteSpace = false;
  151 + $dom->formatOutput = true;
  152 + $res = $dom->load($this->getJobsFilePath());
  153 + if ($res) {
  154 + $func_res = call_user_func($callback,$dom,$additionalParams);
  155 + }
  156 + else {
  157 + $this->sendErrorNotification('Cannot load '.$this->getJobsFilePath());
  158 + }
  159 + }
41 160 }
  161 + else
  162 + $res = FALSE;
42 163  
43   - $res = $this->jobXml->load($this->jobXmlName);
44   - if (!$res)
45   - return array(
46   - "success" => false,
47   - "message" => "Cannot load jobs file");
  164 + fclose($fp);
48 165  
49   - return array("success" => true);
  166 + if ($res)
  167 + return $func_res;
  168 +
  169 + $this->sendErrorNotification('Error during the concurrent access of the jobs manager file');
  170 + return array('success' => false, 'message' => 'Error during the concurrent access of the jobs manager file');
50 171 }
51 172  
52 173 /*
... ... @@ -54,36 +175,33 @@ class IHMJobsManagerClass {
54 175 */
55 176 protected function createJobsFile()
56 177 {
57   - $rootElement = $this->jobXml->createElement('jobs');
58   - $jobsInProgress = $this->jobXml->createElement('jobsInProgress');
  178 + $dom = new DOMDocument("1.0","UTF-8");
  179 + $dom->preserveWhiteSpace = false;
  180 + $dom->formatOutput = true;
  181 +
  182 + $rootElement = $dom->createElement('jobs');
  183 + $jobsInProgress = $dom->createElement('jobsInProgress');
59 184  
60 185 foreach ($this->bkgRootNode as $key => $value)
61 186 {
62   - $element = $this->jobXml->createElement("$key");
  187 + $element = $dom->createElement("$key");
63 188 $element->setAttribute('xml:id',$value);
64 189 $jobsInProgress->appendChild($element);
65 190 }
66   - $jobsFinished = $this->jobXml->createElement('jobsFinished');
  191 + $jobsFinished = $dom->createElement('jobsFinished');
67 192  
68 193 foreach ($this->resRootNode as $key => $value)
69 194 {
70   - $element = $this->jobXml->createElement("$key");
  195 + $element = $dom->createElement("$key");
71 196 $element->setAttribute('xml:id',"$value");
72 197 $jobsFinished->appendChild($element);
73 198 }
74 199  
75 200 $rootElement->appendChild($jobsInProgress);
76 201 $rootElement->appendChild($jobsFinished);
77   - $this->jobXml->appendChild($rootElement);
78   -
79   - $res = $this->jobXml->save($this->jobXmlName);
  202 + $dom->appendChild($rootElement);
80 203  
81   - if (!$res)
82   - return array(
83   - "success" => false,
84   - "message" => "Cannot create new jobs file");
85   -
86   - return array("success" => true);
  204 + return $dom->save($this->getJobsFilePath());
87 205 }
88 206  
89 207 /*
... ... @@ -105,16 +223,6 @@ class IHMJobsManagerClass {
105 223 }
106 224  
107 225 /*
108   - * @brief Decode a request object file
109   - */
110   - public function getRequestObjectFile($id)
111   - {
112   - if (!file_exists($this->getRequestObjectFilePath($id)))
113   - return NULL;
114   - return json_decode(file_get_contents($this->getRequestObjectFilePath($id)));
115   - }
116   -
117   - /*
118 226 * @brief Delete a request object file
119 227 */
120 228 protected function deleteRequestObjectFile($id) {
... ... @@ -137,15 +245,11 @@ class IHMJobsManagerClass {
137 245 }
138 246  
139 247 /*
140   - * @brief delete a job
  248 + * @brief delete a job from job id
141 249 */
142   - public function deleteJob($id)
  250 + protected function deleteJobFromId($dom, $id)
143 251 {
144   - $res = $this->init();
145   - if (!$res['success'])
146   - return $res;
147   -
148   - $job = $this->jobXml->getElementById($id);
  252 + $job = $dom->getElementById($id);
149 253  
150 254 //delete job
151 255 if (!$job)
... ... @@ -179,7 +283,7 @@ class IHMJobsManagerClass {
179 283 $this->deleteRequestObjectFile($id);
180 284  
181 285 $job->parentNode->removeChild($job);
182   - $res = $this->jobXml->save($this->jobXmlName);
  286 + $res = $dom->save($this->getJobsFilePath());
183 287  
184 288 if (!$res)
185 289 return array(
... ... @@ -192,45 +296,24 @@ class IHMJobsManagerClass {
192 296 /*
193 297 * @brief get job info about a job
194 298 */
195   - public function getJobInfo($id)
  299 + protected function getJobInfoById($dom, $id)
196 300 {
197   - $res = $this->init();
198   - if (!$res['success'])
199   - return $res;
200   -
201   - $job = $this->jobXml->getElementById($id);
202   -
203   - $attributes = [];
204   - foreach( $job->attributes as $attrName => $attrNode) {
205   - $attributes[$attrName] = $attrNode->nodeValue;
206   - }
  301 + $job = $dom->getElementById($id);
207 302  
208 303 $format = 'unknown';
209 304 $compression = 'unknown';
210   - if($job)
  305 + if(!$job)
211 306 {
  307 + return array(
  308 + 'success' => false,
  309 + 'message' => "Cannot retrieve job ".$id,
  310 + );
  311 + }
  312 +
  313 + if (!$this->isWSJob) {
  314 + // Not used for a WS job
212 315 $name = $job->getAttribute('name');
213   - $status = $job->getAttribute('status');
214   - $jobType = $job->getAttribute('jobType');
215 316 $info = $job->getAttribute('info');
216   - $start = $job->getAttribute('start');
217   - $stop = $job->getAttribute('stop');
218   - $result = $job->getAttribute('result');
219   - $folder = $job->getAttribute('folder');
220   - $exectime = $job->getAttribute('exectime');
221   - $request_obj = $this->getRequestObjectFile($id);
222   - if (isset($request_obj))
223   - {
224   - if (isset($request_obj->format))
225   - {
226   - $format = strtolower($request_obj->format);
227   - if (($format == "pdf") || ($format == "ps"))
228   - //auto compression for plot request
229   - $compression = ".tar.gz";
230   - }
231   - if (isset($request_obj->compression))
232   - $compression = strtolower($request_obj->compression);
233   - }
234 317 $sendToSamp = $job->getAttribute('sendToSamp');
235 318 if (empty($sendToSamp)) {
236 319 $sendToSamp = false;
... ... @@ -239,37 +322,57 @@ class IHMJobsManagerClass {
239 322 $sendToSamp = ($sendToSamp == "true");
240 323 }
241 324 }
242   - return array(
  325 + $exectime = $job->getAttribute('exectime');
  326 + $status = $job->getAttribute('status');
  327 + $jobType = $job->getAttribute('jobType');
  328 + $start = $job->getAttribute('start');
  329 + $stop = $job->getAttribute('stop');
  330 + $result = $job->getAttribute('result');
  331 + $folder = $job->getAttribute('folder');
  332 + $request_obj = $this->getRequestObjectFile($id);
  333 + if (isset($request_obj))
  334 + {
  335 + if (isset($request_obj->format))
  336 + {
  337 + $format = strtolower($request_obj->format);
  338 + if (($format == "pdf") || ($format == "ps"))
  339 + //auto compression for plot request
  340 + $compression = ".tar.gz";
  341 + }
  342 + if (isset($request_obj->compression))
  343 + $compression = strtolower($request_obj->compression);
  344 + }
  345 +
  346 + $result = array(
243 347 'success' => true,
244 348 'id' => $id,
245   - 'name' => $name,
246 349 'status' => $status,
247   - 'exectime' => $exectime,
248 350 'jobType' => $jobType,
249   - 'info' => $info,
250 351 'start' => $start,
251 352 'stop' => $stop,
252 353 'folder' => $folder,
253 354 'result' => $result,
254 355 'format' => $format,
255 356 'compression' => $compression,
256   - 'sendToSamp' => $sendToSamp,
  357 + 'exectime' => $exectime,
257 358 );
  359 +
  360 + if (!$this->isWSJob) {
  361 + $result['name'] = $name;
  362 + $result['info'] = $info;
  363 + $result['sendToSamp'] = $sendToSamp;
  364 + }
  365 +
  366 + return $result;
258 367 }
259 368  
260 369 /*
261   - * @brief Add a new job
262   - */
263   - public function addJob($obj, $id, $folder, $running, $start, $result, $exitcode, $exectime)
  370 + * @brief Getjob info from request object
  371 + */
  372 + protected function getRequestInfo($obj, $start)
264 373 {
265   - $obj = get_object_vars($obj); // Allow access to elements where the key is in dash-separated form.
266   - $res = $this->init();
267   - if (!$res['success'])
268   - return $res;
269   -
270 374 $infos = [];
271 375 switch ($obj['nodeType']) {
272   - // Data mining
273 376 case 'condition':
274 377 $name = 'datamining_'.time();
275 378 if($obj['name'] != '') {
... ... @@ -279,7 +382,6 @@ class IHMJobsManagerClass {
279 382 $infos['Start date'] = $obj['startDate'];
280 383 $infos['Stop date'] = $obj['stopDate'];
281 384 break;
282   -
283 385 case 'statistics':
284 386 $name = 'statistics_'.time();
285 387 $infos['Name'] = $obj['name']; // TODO: name toujours égal à 'test' (?)
... ... @@ -325,7 +427,6 @@ class IHMJobsManagerClass {
325 427 $infos['Parameters'] = '<ul><li>' . join('</li><li>', $params) . '</li></ul>';
326 428 }
327 429 break;
328   -
329 430 case 'download':
330 431 $name = $obj['downloadSrc'] == '2' ? "download_fits_".time() : "download_data_".time();
331 432 $params = [];
... ... @@ -340,35 +441,25 @@ class IHMJobsManagerClass {
340 441 $infos['Start date'] = $obj['startDate'];
341 442 $infos['Stop date'] = $obj['stopDate'];
342 443 break;
343   -
344   - // Plot
345 444 case 'request':
346 445 $name = "request_".time();
347 446  
348 447 $infos['Output'] = strtolower($obj['file-format']) . ' (' . strtolower($obj['file-output']) . ')';
349   - foreach ($obj['tabs'] as $tab) {
350   - if($tab->id == $obj['last-plotted-tab']) {
351   - $infos['Start date'] = $tab->startDate;
352   - $infos['Stop date'] = $tab->stopDate;
353   -
354   - $strPanels = [];
355   -
356   - foreach ($tab->panels as $panel) {
357   - $strParams = '';
358   - foreach ($panel->params as $param) {
359   - $strParams .= $param->paramid . ($param === end($panel->params) ? '' : ', ');
360   - }
361   - $infos['• Panel ' . $panel->id] = $strParams;
362   - }
  448 + $infos['Start date'] = $obj->startDate;
  449 + $infos['Stop date'] = $obj->stopDate;
363 450  
364   - continue;
  451 + foreach ($obj->panels as $panel) {
  452 + $strParams = '';
  453 + foreach ($panel->params as $param) {
  454 + $strParams .= $param->paramid . ($param === end($panel->params) ? '' : ', ');
365 455 }
  456 + $infos['• Panel ' . $panel->id] = $strParams;
366 457 }
367 458 break;
368   -
369 459 default:
370 460 $name = "unknown_".time();
371 461 }
  462 +
372 463 $infos['Started at'] = gmdate("Y-m-d H:i:s", $start);
373 464  
374 465 $strInfo = '';
... ... @@ -376,84 +467,104 @@ class IHMJobsManagerClass {
376 467 $strInfo .= ($key == 'Started at' ? '<hr/>' : '') . '<b>' . $key . '</b>: ' . $info . '<br/>';
377 468 }
378 469  
379   - $newJob = $this->jobXml->createElement('job');
380   - $newJob->setAttribute('xml:id', $id);
381   - $newJob->setAttribute('jobType', $obj['nodeType']);
382   - $newJob->setAttribute('name', $name);
383   - $newJob->setAttribute('info', $strInfo);
384   - $newJob->setAttribute('folder', $folder);
385   - $newJob->setAttribute('result', $result);
386   - $newJob->setAttribute('start', date('d-m-Y H:i:s', $start));
387   - $newJob->setAttribute('exectime', $exectime);
388   - //to know if know if it's an immediate job or not
389   - $newJob->setAttribute('immediate', !$running);
  470 + return array($name, $strInfo);
  471 + }
  472 +
  473 + /*
  474 + * @brief Get job key
  475 + */
  476 + protected function getJobKey($obj)
  477 + {
  478 + return $obj['nodeType'];
  479 + }
390 480  
391   - $sendToSamp = isset($obj['sendToSamp']) ? $obj['sendToSamp'] : FALSE;
392   - if ($sendToSamp) {
393   - $newJob->setAttribute('sendToSamp', "true");
  481 + /*
  482 + * @brief Add a new job
  483 + */
  484 + protected function addNewJob($dom, $args)
  485 + {
  486 + $obj = get_object_vars($args['obj']); // Allow access to elements where the key is in dash-separated form.
  487 + $key = $this->getJobKey($obj);
  488 +
  489 +
  490 + $newJob = $dom->createElement('job');
  491 + $newJob->setAttribute('xml:id', $args['id']);
  492 + $newJob->setAttribute('jobType', $key);
  493 + $newJob->setAttribute('folder', $args['folder']);
  494 + $newJob->setAttribute('result', $args['result']);
  495 + $newJob->setAttribute('start', date('d-m-Y H:i:s', $args['start']));
  496 + //to know if know if it's an immediate job or not
  497 + $newJob->setAttribute('immediate', !$args['running']);
  498 + $newJob->setAttribute('exectime', $args['exectime']);
  499 + if (!$this->isWSJob) {
  500 + list($name, $strInfo) = $this->getRequestInfo($obj, $args['name']);
  501 + $newJob->setAttribute('name', $name);
  502 + $newJob->setAttribute('info', $strInfo);
  503 + $sendToSamp = isset($obj['sendToSamp']) ? $obj['sendToSamp'] : FALSE;
  504 + if ($sendToSamp) {
  505 + $newJob->setAttribute('sendToSamp', "true");
  506 + }
  507 + }
  508 + else {
  509 + $newJob->setAttribute('user', IHMConfigClass::getUserName());
  510 + $newJob->setAttribute('host', IHMConfigClass::getUserHost());
394 511 }
395 512  
396   - $key = $obj['nodeType'];
397   - if ($running)
  513 +
  514 + if ($args['running'])
398 515 {
399   - $rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$key]);
  516 + $rootJobNode = $dom->getElementById($this->bkgRootNode[$key]);
400 517 if (!$rootJobNode)
401 518 {
402   - $rootJobNode = $this->jobXml->createElement("$key");
  519 + $rootJobNode = $dom->createElement("$key");
403 520 $rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$key]);
404   - $jobsInProgress = $this->jobXml->getElementsByTagName('jobsInProgress')->item(0);
  521 + $jobsInProgress = $dom->getElementsByTagName('jobsInProgress')->item(0);
405 522 $jobsInProgress->appendChild($rootJobNode);
406 523 }
407 524 }
408 525 else
409 526 {
410   - $rootJobNode = $this->jobXml->getElementById($this->resRootNode[$key]);
  527 + $rootJobNode = $dom->getElementById($this->resRootNode[$key]);
411 528 if (!$rootJobNode)
412 529 {
413   - $rootJobNode = $this->jobXml->createElement("$key");
  530 + $rootJobNode = $dom->createElement("$key");
414 531 $rootJobNode->setAttribute('xml:id', $this->resRootNode[$key]);
415   - $jobsFinished = $this->jobXml->getElementsByTagName('jobsFinished')->item(0);
  532 + $jobsFinished = $dom->getElementsByTagName('jobsFinished')->item(0);
416 533 $jobsFinished->appendChild($rootJobNode);
417 534 }
418 535 }
419 536  
420 537 $rootJobNode->appendChild($newJob);
421 538  
422   - if (!$this->jobXml->save($this->jobXmlName))
  539 + if (!$dom->save($this->getJobsFilePath()))
423 540 return array("success" => false, "message" => "Cannot save job manager file");
424 541  
425   - $this->saveRequestObjectFile($obj, $id);
  542 + $this->saveRequestObjectFile($obj, $args['id']);
426 543  
427   - $this->updateJobStatus($id, $running, $exitcode, $exectime);
  544 + $this->updateJobStatusById($dom, $args);
428 545  
429   - return $this->getJobInfo($id);
  546 + return $this->getJobInfoById($dom, $args['id']);
430 547 }
431 548  
432 549 /*
433   - * @brief Update the status of a job
  550 + * @brief Update the status of a job by id
434 551 */
435   - public function updateJobStatus($id, $running, $exitcode, $exectime = 0)
  552 + protected function updateJobStatusById($dom, $args)
436 553 {
437   - $res = $this->init();
438   - if (!$res['success'])
439   - return $res;
440   -
441   - $this->lockService();
442   -
443   - $job = $this->jobXml->getElementById($id);
  554 + $job = $dom->getElementById($args['id']);
444 555  
445 556 if (!isset($job)) {
446 557 return array("success" => false, "message" => "Cannot found job");
447 558 }
448 559  
449   - $jobstatus = $this->getJobStatus($running,$exitcode);
  560 + $jobstatus = $this->getJobStatus($args['running'], $args['exitcode']);
450 561 $job->setAttribute('status', $jobstatus);
451 562  
452   - $job->setAttribute('exectime', $exectime);
  563 + $job->setAttribute('exectime', $args['exectime']);
453 564  
454 565 $infos = [];
455 566  
456   - if ($running) {
  567 + if ($args['running']) {
457 568 $job->setAttribute('stop', 'unknown');
458 569 } else if ($job->getAttribute('stop') == '' || $job->getAttribute('stop') == 'unknown') {
459 570 $job->setAttribute('stop', date('d-m-Y H:i:s', time()));
... ... @@ -462,31 +573,33 @@ class IHMJobsManagerClass {
462 573 $interval = (new DateTime('now'))->diff($start);
463 574 $infos['Job duration'] = $interval->format('%Hh %Im %Ss');
464 575  
465   - $resPath = glob(USERWORKINGDIR . $job->getAttribute('folder') . '/' . $job->getAttribute('result') . '*')[0];
  576 + if (!$this->isWSJob) {
  577 + $resPath = glob(USERWORKINGDIR . $job->getAttribute('folder') . '/' . $job->getAttribute('result') . '*')[0];
466 578  
467   - if($job->getAttribute('jobType') == 'condition') {
468   - $resXml = new DomDocument();
469   - $resXml->load($resPath);
470   - $infos['nb intervals'] = $resXml->getElementsByTagName('nbIntervals')->item(0)->nodeValue;
471   - }
  579 + if($job->getAttribute('jobType') == 'condition') {
  580 + $resXml = new DomDocument();
  581 + $resXml->load($resPath);
  582 + $infos['nb intervals'] = $resXml->getElementsByTagName('nbIntervals')->item(0)->nodeValue;
  583 + }
472 584  
473   - $fileSize = filesize($resPath);
474   - if ($fileSize < 1024) {
475   - $strSize = number_format($fileSize, 2, '.', ' ') . 'b';
476   - } else if($fileSize < 1024*1024) {
477   - $strSize = number_format($fileSize/1024, 2, '.', ' ') . 'kb';
478   - } else if($fileSize < 1024*1024*1024) {
479   - $strSize = number_format($fileSize/(1024*1024), 2, '.', ' ') . 'mb';
480   - } else {
481   - $strSize = number_format($fileSize/(1024*1024*1024), 2, '.', ' ') . 'gb';
  585 + $fileSize = filesize($resPath);
  586 + if ($fileSize < 1024) {
  587 + $strSize = number_format($fileSize, 2, '.', ' ') . 'b';
  588 + } else if($fileSize < 1024*1024) {
  589 + $strSize = number_format($fileSize/1024, 2, '.', ' ') . 'kb';
  590 + } else if($fileSize < 1024*1024*1024) {
  591 + $strSize = number_format($fileSize/(1024*1024), 2, '.', ' ') . 'mb';
  592 + } else {
  593 + $strSize = number_format($fileSize/(1024*1024*1024), 2, '.', ' ') . 'gb';
  594 + }
  595 + $infos['File size'] = $strSize;
482 596 }
483   - $infos['File size'] = $strSize;
484 597  
485   - $this->jobXml->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job);
  598 + $dom->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job);
486 599 }
487 600  
488   - if($exitcode != 0) {
489   - $infos['Error code'] = $exitcode;
  601 + if($args['exitcode'] != 0) {
  602 + $infos['Error code'] = $args['exitcode'];
490 603 }
491 604  
492 605 $strInfo = $job->getAttribute('info');
... ... @@ -495,30 +608,22 @@ class IHMJobsManagerClass {
495 608 }
496 609 $job->setAttribute('info', $strInfo);
497 610  
498   - $res = $this->jobXml->save($this->jobXmlName);
499   -
500   - $this->unlockService();
  611 + $res = $dom->save($this->getJobsFilePath());
501 612  
502 613 if (!$res)
503 614 return array(
504 615 'success' => false,
505 616 'message' => "Cannot save jobs status file");
506 617  
507   - return $this->getJobInfo($id);
  618 + return $this->getJobInfoById($dom, $args['id']);
508 619 }
509 620  
510   - public function lockService(){}
511   - public function unlockService(){}
512 621 /*
513   - * @brief Get the list of jobs with a specific status
  622 + * @brief Get the list of jobs with a specific status in a $dom
514 623 */
515   - public function getJobsByStatus($status)
  624 + protected function getJobsByStatusInDom($dom, $status)
516 625 {
517   - $res = $this->init();
518   - if (!$res['success'])
519   - return $res;
520   -
521   - $xp = new domxpath($this->jobXml);
  626 + $xp = new domxpath($dom);
522 627 $jobs = $xp->query("//job[@status='".$status."']");
523 628  
524 629 $jobsId = array();
... ... @@ -529,15 +634,11 @@ class IHMJobsManagerClass {
529 634 }
530 635  
531 636 /*
532   - * @brief Get jobs that use a specific working dir
  637 + * @brief Get jobs that use a specific working dir in a $dom
533 638 */
534   - public function getJobsByWorkingDir($folder)
  639 + protected function getJobsByWorkingDirInDom($dom, $folder)
535 640 {
536   - $res = $this->init();
537   - if (!$res['success'])
538   - return $res;
539   -
540   - $xp = new domxpath($this->jobXml);
  641 + $xp = new domxpath($dom);
541 642 $jobs = $xp->query("//job[@folder='".$folder."']");
542 643  
543 644 $jobsId = array();
... ... @@ -548,16 +649,12 @@ class IHMJobsManagerClass {
548 649 }
549 650  
550 651 /*
551   - * @brief Get all jobs to clean (immediate result jobs)
  652 + * @brief Get all jobs to clean (immediate result jobs) in a $dom
552 653 */
553   - public function getJobsToClean()
  654 + protected function getJobsToCleanInDom($dom)
554 655 {
555   - $res = $this->init();
556   - if (!$res['success'])
557   - return $res;
558   -
559 656 // Get immediate jobs
560   - $xp = new domxpath($this->jobXml);
  657 + $xp = new domxpath($dom);
561 658 $jobs = $xp->query("//job[@immediate='1']");
562 659  
563 660 $jobsId = array();
... ...
src/InputOutput/WSImpl/Config/WSConfigClass.php
... ... @@ -45,22 +45,6 @@ class WSConfigClass
45 45 return IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$jobsFile;
46 46 }
47 47  
48   - public static function lockServices()
49   - {
50   - touch(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile);
51   - }
52   -
53   - public static function isLockedServices()
54   - {
55   - return file_exists(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile);
56   - }
57   -
58   - public static function unlockServices()
59   - {
60   - if (file_exists(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile))
61   - unlink(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile);
62   - }
63   -
64 48 public static function getDataSetInfoDir()
65 49 {
66 50 return IHMConfigClass::getGenericDataPath().self::$dataSetInfoDir.'/';
... ...
src/InputOutput/WSImpl/Params/DownloadImpl/WSInputOutputParamsDownloadClass.php
... ... @@ -15,6 +15,15 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
15 15 $this->paramManager = new IHMParamManagerClass();
16 16 $this->jobsManager = new WSJobsManagerClass();
17 17 }
  18 +
  19 + /*
  20 + * @brief Get Task
  21 + */
  22 + protected function getTask($input)
  23 + {
  24 + return WSInputOutputClass::getService();
  25 + }
  26 +
18 27 /*
19 28 * @brief method to unmarshall a download request
20 29 */
... ... @@ -71,7 +80,7 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
71 80  
72 81 foreach ($input->list as $param)
73 82 {
74   - $paramInfo = $this->paramManager->addExistingParam($param->paramid, $this->paramsData, $param->template_args);
  83 + $paramInfo = $this->paramManager->addExistingParam($param->paramid, $this->paramsData/*, $param->template_args*/);
75 84 // $this->paramManager->applyRangesAndIndexes($this->paramsData, $param, FALSE, $paramInfo);
76 85  
77 86 $downloadNode->addParam($paramInfo['id'],$paramInfo['indexes'],$paramInfo['calib_infos']);
... ... @@ -137,7 +146,7 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
137 146 /*
138 147 * @brief Unmarshall the time definition from the WS request
139 148 */
140   - protected function unmarshallTimeDefinition($input, $requestIndex)
  149 + protected function unmarshallTimeDefinition($input, $requestIndex, $ttFileIndex = -1, $ttIntIndex = -1)
141 150 {
142 151 $requestNodes = $this->paramsData->getRequestNodes();
143 152 $timesNode = $requestNodes[$requestIndex]->getTimesNode();
... ... @@ -156,15 +165,18 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
156 165 protected function addToJobsFile($data,$resultKey)
157 166 {
158 167 $waitingResult = $data->getWaitingResult($resultKey);
159   -
160   - return $this->jobsManager->addJob(
  168 +
  169 + $result = $this->jobsManager->addJob(
161 170 $this->input,
162 171 $data->getId(),
163 172 $this->getWorkingDirName(),
164 173 $data->getStatus() == ProcessStatusEnumClass::RUNNING,
165 174 $data->getStart(),
166 175 $waitingResult,
167   - $data->getErrorCode());
  176 + $data->getErrorCode(),
  177 + $data->getExecTime());
  178 +
  179 + return $result;
168 180 }
169 181  
170 182 protected function getDatasetIdFromParamInfo($paramId)
... ...
src/InputOutput/WSImpl/Params/PlotImpl/WSInputOutputParamsPlotClass.php
... ... @@ -14,6 +14,14 @@ class WSInputOutputParamsPlotClass extends IHMInputOutputParamsAbstractClass
14 14 $this->paramManager = new IHMParamManagerClass();
15 15 $this->jobsManager = new WSJobsManagerClass();
16 16 }
  17 +
  18 + /*
  19 + * @brief Get Task
  20 + */
  21 + protected function getTask($input)
  22 + {
  23 + return WSInputOutputClass::getService();
  24 + }
17 25  
18 26 /*
19 27 * @brief method to unmarshall a plot request
... ... @@ -170,7 +178,8 @@ class WSInputOutputParamsPlotClass extends IHMInputOutputParamsAbstractClass
170 178 $data->getStatus() == ProcessStatusEnumClass::RUNNING,
171 179 $data->getStart(),
172 180 $waitingResult,
173   - $data->getErrorCode());
  181 + $data->getErrorCode(),
  182 + $data->getExecTime());
174 183 }
175 184  
176 185 /*
... ...
src/InputOutput/WSImpl/Tools/WSJobsManagerClass.php
... ... @@ -23,211 +23,25 @@ class WSJobsManagerClass extends IHMJobsManagerClass {
23 23 */
24 24 function __construct()
25 25 {
  26 + $this->isWSJob = TRUE;
26 27 }
27 28  
28   - /*
29   - * @brief Load jobs file and create it if needed
30   - */
31   - protected function init()
32   - {
33   - $this->jobXmlName = WSConfigClass::getWsJobsFile();
34   - $this->jobXml = new DomDocument("1.0");
35   -
36   - if (!file_exists($this->jobXmlName))
37   - {
38   - $res = $this->createJobsFile();
39   - if (!$res['success']) {
40   - error_log("WebServices Error : Cannot create WSjobs.xml", 1, email);
41   - return $res;
42   - }
43   - }
44   -
45   - while (WSConfigClass::isLockedServices())
46   - sleep(1);
47   -
48   - $res = $this->jobXml->load($this->jobXmlName);
49   - if (!$res) {
50   - error_log("WebServices Error : Cannot load WSjobs.xml", 1, email);
51   - return array(
52   - "success" => false,
53   - "message" => "Cannot load jobs file");
54   - }
55   -
56   - return array("success" => true);
57   - }
58   -
59   - /*
60   - * @brief get job info about a job
61   - */
62   - public function getJobInfo($id)
63   - {
64   - $res = $this->init();
65   - if (!$res['success'])
66   - return $res;
67   -
68   - $job = $this->jobXml->getElementById($id);
69   - $format = 'unknown';
70   - $compression = 'unknown';
71   - if($job)
72   - {
73   - // $name = $job->getAttribute('name');
74   - $status = $job->getAttribute('status');
75   - $jobType = $job->getAttribute('jobType');
76   - // $info = $job->getAttribute('info');
77   - $start = $job->getAttribute('start');
78   - $stop = $job->getAttribute('stop');
79   - $result = $job->getAttribute('result');
80   - $folder = $job->getAttribute('folder');
81   - $request_obj = $this->getRequestObjectFile($id);
82   - if (isset($request_obj))
83   - {
84   - if (isset($request_obj->fileformat))
85   - {
86   - $format = strtolower($request_obj->format);
87   - if (($format == "pdf") || ($format == "ps"))
88   - //auto compression for plot request
89   - $compression = ".tar.gz";
90   -
91   - // if ($format == "ascii") $format = 'txt';
92   - }
93   - if (isset($request_obj->compression))
94   - $compression = strtolower($request_obj->compression);
95   - }
96   - }
97   - return array(
98   - 'success' => true,
99   - 'id' => $id,
100   - // 'name' => $name,
101   - 'status' => $status,
102   - 'jobType' => $jobType,
103   - // 'info' => $info,
104   - 'start' => $start,
105   - 'stop' => $stop,
106   - 'folder' => $folder,
107   - 'result' => $result,
108   - 'format' => $format,
109   - 'compression' => $compression
110   - );
111   - }
112   -
113   - public function lockService(){
114   - if (!WSConfigClass::isLockedServices())
115   - WSConfigClass::lockServices();
116   - }
117   -
118   - public function unlockService(){
119   - if (WSConfigClass::isLockedServices())
120   - WSConfigClass::unlockServices();
121   - }
122   - /*
123   - * @brief Add a new job
124   - */
125   - public function addJob($obj, $id, $folder,
126   - $running, $start, $result, $exitcode)
127   - {
128   - $res = $this->init();
129   -
130   - if (!$res['success'])
131   - return $res;
132   -
133   - $this->lockService();
134   -
135   - $key = WSInputOutputClass::getService();
136   -
137   - $newJob = $this->jobXml->createElement('job');
138   -
139   - $newJob->setAttribute('xml:id', $id);
140   - $newJob->setAttribute('jobType', $key);
141   -
142   - $newJob->setAttribute('result', $result);
143   - $newJob->setAttribute('folder', $folder);
144   - $newJob->setAttribute('start', date('d-m-Y H:i:s', $start));
145   - $newJob->setAttribute('user', IHMConfigClass::getUserName());
146   - $newJob->setAttribute('host', IHMConfigClass::getUserHost());
  29 + protected function getJobsFilePath()
  30 + {
  31 + return WSConfigClass::getWsJobsFile();
  32 + }
147 33  
148   - if ($running)
149   - {
150   - $rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$key]);
151   - if (!$rootJobNode)
152   - {
153   - $rootJobNode = $this->jobXml->createElement("$key");
154   - $rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$key]);
155   - $jobsInProgress = $this->jobXml->getElementsByTagName('jobsInProgress')->item(0);
156   - $jobsInProgress->appendChild($rootJobNode);
157   - }
158   - }
159   - else
160   - {
161   - $rootJobNode = $this->jobXml->getElementById($this->resRootNode[$key]);
162   - if (!$rootJobNode)
163   - {
164   - $rootJobNode = $this->jobXml->createElement("$key");
165   - $rootJobNode->setAttribute('xml:id', $this->resRootNode[$key]);
166   - $jobsFinished = $this->jobXml->getElementsByTagName('jobsFinished')->item(0);
167   - $jobsFinished->appendChild($rootJobNode);
168   - }
169   - }
170   -
171   - $rootJobNode->appendChild($newJob);
172   -
173   - if (!$this->jobXml->save($this->jobXmlName)) {
174   - $this->unlockService();
175   - return array("success" => false, "message" => "Cannot save job manager file");
176   - }
177   - $this->unlockService();
178   - $this->saveRequestObjectFile($obj, $id);
179   -
180   - $res = $this->updateJobStatus($id, $running, $exitcode);
181   -
182   - return $res;
183   -
  34 + protected function sendErrorNotification($message) {
  35 + error_log("WebServices Error : ".$message);
  36 + error_log("WebServices Error : ".$message, email);
184 37 }
185 38  
186   -
187 39 /*
188   - * @brief delete a job
189   - */
190   - public function deleteJob($id)
  40 + * @brief Get job key
  41 + */
  42 + protected function getJobKey($obj)
191 43 {
192   - $res = $this->init();
193   - if (!$res['success'])
194   - return $res;
195   -
196   - $job = $this->jobXml->getElementById($id);
197   -
198   - //delete job
199   - if (!$job)
200   - return array('success' => false, 'message' => "Job not reachable");
201   -
202   - $folder = $job->getAttribute('folder');
203   -
204   - //be sure that it's an AMDA working dir before deletion...
205   - $fullFolderPath = IHMConfigClass::getRequestPath().$folder.'/';
206   -
207   - if ((isset($folder)) &&
208   - ($folder != "") &&
209   - is_dir($fullFolderPath) &&
210   - (preg_match("/DD[0-9A-Za-z]*_/",$folder) ||
211   - preg_match("/Plot[0-9]*_/",$folder)))
212   - {
213   - foreach (glob($fullFolderPath.'*') as $filename)
214   - {
215   - if (is_dir($filename) && (basename($filename) == 'params'))
216   - {
217   - //recursive deletion only for "params" dir (a full recursive deletion is probably too dangerous...)
218   - foreach (glob($filename.'/*') as $paramname)
219   - unlink($paramname);
220   - rmdir($filename);
221   - }
222   - else
223   - unlink($filename);
224   - }
225   - rmdir($fullFolderPath);
226   - }
227   -
228   - $this->deleteRequestObjectFile($id);
229   -
230   - return array('success' => true, 'id' => $id);
  44 + return WSInputOutputClass::getService();
231 45 }
232 46  
233 47 public function getResultFromProcessId($id)
... ...
src/Request/ProcessRequestImpl/ProcessRequestClass.php
... ... @@ -96,7 +96,7 @@ class ProcessRequestClass extends RequestAbstractClass
96 96 $this->requestData->setErrorMsg($processInfo['errormsg']);
97 97 }
98 98 $this->requestData->setExecTime($processInfo['exectime']);
99   - $processMgr->deleteProcess($processInfo['id'], $result['success']);
  99 + $processMgr->deleteProcess($processInfo['id']);
100 100 }
101 101  
102 102 $this->requestData->setStart($processInfo['runningstart']);
... ...