1
|
|
|
<?php namespace Comodojo\Extender\Task; |
2
|
|
|
|
3
|
|
|
use \Comodojo\Extender\Components\Database; |
4
|
|
|
use \Comodojo\Extender\Task\Table as TasksTable; |
5
|
|
|
use \Comodojo\Extender\Events\TaskEvent; |
6
|
|
|
use \Comodojo\Extender\Events\WorklogEvent; |
7
|
|
|
use \Comodojo\Foundation\Base\Configuration; |
8
|
|
|
use \Comodojo\Foundation\Events\Manager as EventsManager; |
9
|
|
|
use \Comodojo\Foundation\Logging\LoggerTrait; |
10
|
|
|
use \Comodojo\Foundation\Events\EventsTrait; |
11
|
|
|
use \Comodojo\Foundation\Base\ConfigurationTrait; |
12
|
|
|
use \Comodojo\Extender\Traits\TasksTableTrait; |
13
|
|
|
use \Comodojo\Extender\Traits\TaskErrorHandlerTrait; |
14
|
|
|
use \Comodojo\Extender\Orm\Entities\Worklog; |
15
|
|
|
use \Comodojo\Extender\Utils\StopWatch; |
16
|
|
|
use \Psr\Log\LoggerInterface; |
17
|
|
|
use \Doctrine\ORM\EntityManager; |
18
|
|
|
use \Comodojo\Exception\TaskException; |
19
|
|
|
use \Exception; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @package Comodojo Extender |
23
|
|
|
* @author Marco Giovinazzi <[email protected]> |
24
|
|
|
* @license MIT |
25
|
|
|
* |
26
|
|
|
* LICENSE: |
27
|
|
|
* |
28
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
29
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
30
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
31
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
32
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
33
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
34
|
|
|
* THE SOFTWARE. |
35
|
|
|
*/ |
36
|
|
|
|
37
|
|
|
class Runner { |
38
|
|
|
|
39
|
|
|
use LoggerTrait; |
40
|
|
|
use ConfigurationTrait; |
41
|
|
|
use EventsTrait; |
42
|
|
|
use TasksTableTrait; |
43
|
|
|
use TaskErrorHandlerTrait; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var int |
47
|
|
|
*/ |
48
|
|
|
protected $worklog_id; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var StopWatch |
52
|
|
|
*/ |
53
|
|
|
protected $stopwatch; |
54
|
|
|
|
55
|
|
|
public function __construct( |
56
|
|
|
Configuration $configuration, |
57
|
|
|
LoggerInterface $logger, |
58
|
|
|
TasksTable $table, |
59
|
|
|
EventsManager $events |
60
|
|
|
) { |
61
|
|
|
|
62
|
|
|
// init components |
63
|
|
|
$this->setConfiguration($configuration); |
64
|
|
|
$this->setLogger($logger); |
65
|
|
|
$this->setEvents($events); |
66
|
|
|
$this->setTasksTable($table); |
67
|
|
|
|
68
|
|
|
// create StopWatch |
69
|
|
|
$this->stopwatch = new StopWatch(); |
70
|
|
|
|
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
public function run(Request $request) { |
74
|
|
|
|
75
|
|
|
$name = $request->getName(); |
76
|
|
|
$task = $request->getTask(); |
77
|
|
|
$uid = $request->getUid(); |
78
|
|
|
$jid = $request->getJid(); |
79
|
|
|
$puid = $request->getParentUid(); |
80
|
|
|
$parameters = $request->getParameters(); |
81
|
|
|
|
82
|
|
|
ob_start(); |
83
|
|
|
|
84
|
|
|
try { |
85
|
|
|
|
86
|
|
|
$this->stopwatch->start(); |
87
|
|
|
|
88
|
|
|
$this->logger->notice("Starting new task $task ($name)"); |
89
|
|
|
|
90
|
|
|
$thetask = $this->table->get($task)->getInstance($name, $parameters); |
91
|
|
|
|
92
|
|
|
$this->events->emit( new TaskEvent('start', $thetask) ); |
93
|
|
|
|
94
|
|
|
$pid = $thetask->getPid(); |
95
|
|
|
|
96
|
|
|
$this->openWorklog( |
97
|
|
|
$uid, |
98
|
|
|
$puid, |
99
|
|
|
$pid, |
100
|
|
|
$name, |
101
|
|
|
$jid, |
102
|
|
|
$task, |
103
|
|
|
$parameters, |
104
|
|
|
$this->stopwatch->getStartTime() |
105
|
|
|
); |
106
|
|
|
|
107
|
|
|
$this->installErrorHandler(); |
108
|
|
|
|
109
|
|
|
try { |
110
|
|
|
|
111
|
|
|
$result = $thetask->run(); |
112
|
|
|
|
113
|
|
|
$status = Worklog::STATUS_COMPLETE; |
114
|
|
|
|
115
|
|
|
$this->events->emit( new TaskEvent('complete', $thetask) ); |
116
|
|
|
|
117
|
|
|
} catch (TaskException $te) { |
118
|
|
|
|
119
|
|
|
$status = Worklog::STATUS_ABORT; |
120
|
|
|
|
121
|
|
|
$result = $te->getMessage(); |
122
|
|
|
|
123
|
|
|
$this->events->emit( new TaskEvent('abort', $thetask) ); |
124
|
|
|
|
125
|
|
|
} catch (Exception $e) { |
126
|
|
|
|
127
|
|
|
$status = Worklog::STATUS_ERROR; |
128
|
|
|
|
129
|
|
|
$result = $e->getMessage(); |
130
|
|
|
|
131
|
|
|
$this->events->emit( new TaskEvent('error', $thetask) ); |
132
|
|
|
|
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
$this->restoreErrorHandler(); |
136
|
|
|
|
137
|
|
|
$this->events->emit( new TaskEvent('stop', $thetask) ); |
138
|
|
|
|
139
|
|
|
$this->stopwatch->stop(); |
140
|
|
|
|
141
|
|
|
$this->closeWorklog($status, $result, $this->stopwatch->getStopTime()); |
142
|
|
|
|
143
|
|
|
$drift = $this->stopwatch->getDrift()->format('%s'); |
144
|
|
|
|
145
|
|
|
$this->logger->notice("Task $name ($task) pid $pid ends in ".($status === Worklog::STATUS_COMPLETE ? 'success' : 'error')." in $drift secs"); |
146
|
|
|
|
147
|
|
|
} catch (Exception $e) { |
148
|
|
|
|
149
|
|
|
ob_end_clean(); |
150
|
|
|
|
151
|
|
|
throw $e; |
152
|
|
|
|
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
$result = new Result([ |
156
|
|
|
$uid, |
157
|
|
|
$pid, |
158
|
|
|
$jid, |
159
|
|
|
$name, |
160
|
|
|
$status === Worklog::STATUS_COMPLETE ? true : false, |
161
|
|
|
$this->stopwatch->getStartTime(), |
162
|
|
|
$this->stopwatch->getStopTime(), |
163
|
|
|
$result, |
164
|
|
|
$this->worklog_id |
165
|
|
|
]); |
166
|
|
|
|
167
|
|
|
$this->stopwatch->clear(); |
168
|
|
|
|
169
|
|
|
ob_end_clean(); |
170
|
|
|
|
171
|
|
|
$this->events->emit( new TaskEvent(self::statusToEvent($status), $thetask, $result) ); |
172
|
|
|
|
173
|
|
|
return $result; |
174
|
|
|
|
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
public static function fastStart( |
178
|
|
|
Request $request, |
179
|
|
|
Configuration $configuration, |
180
|
|
|
LoggerInterface $logger, |
181
|
|
|
TasksTable $table, |
182
|
|
|
EventsManager $events, |
183
|
|
|
EntityManager $em = null |
184
|
|
|
) { |
185
|
|
|
|
186
|
|
|
$runner = new Runner( |
187
|
|
|
$configuration, |
188
|
|
|
$logger, |
189
|
|
|
$table, |
190
|
|
|
$events, |
191
|
|
|
$em |
|
|
|
|
192
|
|
|
); |
193
|
|
|
|
194
|
|
|
return $runner->run($request); |
195
|
|
|
|
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
protected function openWorklog( |
199
|
|
|
$uid, |
200
|
|
|
$puid, |
201
|
|
|
$pid, |
202
|
|
|
$name, |
203
|
|
|
$jid, |
204
|
|
|
$task, |
205
|
|
|
$parameters, |
206
|
|
|
$start |
207
|
|
|
) { |
208
|
|
|
|
209
|
|
|
try { |
210
|
|
|
|
211
|
|
|
$em = Database::init($this->getConfiguration())->getEntityManager(); |
212
|
|
|
|
213
|
|
|
$worklog = new Worklog(); |
214
|
|
|
|
215
|
|
|
$worklog |
216
|
|
|
->setUid($uid) |
217
|
|
|
->setParentUid($puid) |
218
|
|
|
->setPid($pid) |
219
|
|
|
->setName($name) |
220
|
|
|
->setStatus(Worklog::STATUS_RUN) |
221
|
|
|
->setTask($task) |
222
|
|
|
->setParameters($parameters) |
223
|
|
|
->setStartTime($start); |
224
|
|
|
|
225
|
|
|
if ( $jid !== null ) { |
226
|
|
|
$schedule = $em->find('\Comodojo\Extender\Orm\Entities\Schedule', $jid); |
227
|
|
|
$worklog->setJid($schedule); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
$this->events->emit( new WorklogEvent('open', $worklog) ); |
231
|
|
|
|
232
|
|
|
$em->persist($worklog); |
233
|
|
|
$em->flush(); |
234
|
|
|
|
235
|
|
|
$this->worklog_id = $worklog->getId(); |
236
|
|
|
|
237
|
|
|
//$em->getConnection()->close(); |
|
|
|
|
238
|
|
|
$em->close(); |
239
|
|
|
|
240
|
|
|
} catch (Exception $e) { |
241
|
|
|
throw $e; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
protected function closeWorklog( |
247
|
|
|
$status, |
248
|
|
|
$result, |
249
|
|
|
$end |
250
|
|
|
) { |
251
|
|
|
|
252
|
|
|
try { |
253
|
|
|
|
254
|
|
|
$em = Database::init($this->getConfiguration())->getEntityManager(); |
255
|
|
|
|
256
|
|
|
$worklog = $em->find('\Comodojo\Extender\Orm\Entities\Worklog', $this->worklog_id); |
257
|
|
|
|
258
|
|
|
$worklog |
259
|
|
|
->setStatus($status) |
260
|
|
|
->setResult($result) |
261
|
|
|
->setEndTime($end); |
262
|
|
|
|
263
|
|
|
$jid = $worklog->getJid(); |
264
|
|
|
if ( $jid !== null ) { |
265
|
|
|
$schedule = $em->find('\Comodojo\Extender\Orm\Entities\Schedule', $jid); |
266
|
|
|
$worklog->setJid($schedule); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
$this->events->emit( new WorklogEvent('close', $worklog) ); |
270
|
|
|
|
271
|
|
|
$em->persist($worklog); |
272
|
|
|
$em->flush(); |
273
|
|
|
//$em->getConnection()->close(); |
|
|
|
|
274
|
|
|
$em->close(); |
275
|
|
|
|
276
|
|
|
} catch (Exception $e) { |
277
|
|
|
throw $e; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
protected function statusToEvent($status) { |
283
|
|
|
|
284
|
|
|
switch ($status) { |
285
|
|
|
case Worklog::STATUS_COMPLETE: |
286
|
|
|
return 'complete'; |
287
|
|
|
break; |
|
|
|
|
288
|
|
|
case Worklog::STATUS_ABORT: |
289
|
|
|
return 'abort'; |
290
|
|
|
break; |
|
|
|
|
291
|
|
|
case Worklog::STATUS_ERROR: |
292
|
|
|
return 'error'; |
293
|
|
|
break; |
|
|
|
|
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
} |
299
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.