Completed
Push — master ( e481c7...bcdb1b )
by Marco
35:35 queued 20:00
created

Runner::closeWorklog()   B

Complexity

Conditions 3
Paths 16

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 17
nc 16
nop 3
dl 0
loc 32
rs 8.8571
c 0
b 0
f 0
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) );
0 ignored issues
show
Bug Best Practice introduced by
The method Comodojo\Extender\Task\Runner::statusToEvent() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

171
        $this->events->emit( new TaskEvent(self::/** @scrutinizer ignore-call */ statusToEvent($status), $thetask, $result) );
Loading history...
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
0 ignored issues
show
Unused Code introduced by
The call to Comodojo\Extender\Task\Runner::__construct() has too many arguments starting with $em. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

191
        $runner = /** @scrutinizer ignore-call */ new Runner(

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. Please note the @ignore annotation hint above.

Loading history...
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;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
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