Completed
Push — 2.0 ( dd3689...ee0168 )
by Marco
12:16
created

Runner::forker()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 64
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 64
rs 8.6346
cc 5
eloc 29
nc 5
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Comodojo\Extender\Jobs;
2
3
use \Comodojo\Extender\Components\Ipc;
4
use \Comodojo\Extender\Components\Database;
5
use \Comodojo\Extender\Tasks\Table as TasksTable;
6
use \Comodojo\Extender\Tasks\Runner as TasksRunner;
7
use \Comodojo\Extender\Utils\ProcessTools;
8
use \Comodojo\Extender\Utils\Checks;
9
use \Comodojo\Extender\Utils\Validator;
10
use \Comodojo\Extender\Events\JobEvent;
11
use \Comodojo\Extender\Events\JobStatusEvent;
12
use \Comodojo\Dispatcher\Components\Configuration;
13
use \Comodojo\Dispatcher\Components\EventsManager;
14
use \Psr\Log\LoggerInterface;
15
use \Exception;
16
17
/**
18
 * Job runner
19
 *
20
 * @package     Comodojo extender
21
 * @author      Marco Giovinazzi <[email protected]>
22
 * @license     GPL-3.0+
23
 *
24
 * LICENSE:
25
 *
26
 * This program is free software: you can redistribute it and/or modify
27
 * it under the terms of the GNU Affero General Public License as
28
 * published by the Free Software Foundation, either version 3 of the
29
 * License, or (at your option) any later version.
30
 *
31
 * This program is distributed in the hope that it will be useful,
32
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34
 * GNU Affero General Public License for more details.
35
 *
36
 * You should have received a copy of the GNU Affero General Public License
37
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38
 */
39
40
class Runner {
41
42
    protected $configuration;
43
44
    protected $logger;
45
46
    protected $tasks;
47
48
    protected $events;
49
50
    protected $ipc;
51
52
    protected $manager;
53
54
    protected $lagger_timeout;
55
56
    protected $max_runtime;
57
58
    protected $max_childs;
59
60
    private $multithread;
61
62
    private $runner;
63
64
    private $active = true;
0 ignored issues
show
Unused Code introduced by
The property $active is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
65
66
    public function __construct(
67
        Configuration $configuration,
68
        LoggerInterface $logger,
69
        TasksTable $tasks,
70
        EventsManager $events
71
    ) {
72
73
        $this->configuration = $configuration;
74
        $this->logger = $logger;
75
        $this->tasks = $tasks;
76
        $this->events = $events;
77
        $this->ipc = new Ipc($configuration);
78
        $this->manager = new Manager($this->configuration, $this->logger);
79
80
        // init the runner
81
        $this->runner = new TasksRunner(
82
            $this->configuration,
83
            $this->logger,
84
            $this->tasks,
85
            $this->events,
86
            Database::init($configuration)
87
        );
88
89
        // retrieve parameters
90
        $this->lagger_timeout = Validator::laggerTimeout($this->configuration->get('child-lagger-timeout'));
91
        $this->multithread = Validator::multithread($this->configuration->get('multithread'));
92
        $this->max_runtime = Validator::maxChildRuntime($this->configuration->get('child-max-runtime'));
93
        $this->max_childs = Validator::forkLimit($this->configuration->get('fork-limit'));
94
95
        $this->logger->debug("Jobs runner online", array(
96
            'lagger_timeout' => $this->lagger_timeout,
97
            'multithread' => $this->multithread,
98
            'max_runtime' => $this->max_runtime,
99
            'max_childs' => $this->max_childs
100
        ));
101
102
    }
103
104
    public function __destruct() {
105
106
        $this->manager->release();
107
108
    }
109
110
    public function add(Job $job) {
111
112
        if ( $this->tasks->get($job->task) === null ) {
0 ignored issues
show
Documentation introduced by
The property task does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
113
114
            $this->logger->error("Cannot add job ".$job->name.": missing task ".$job->task);
0 ignored issues
show
Documentation introduced by
The property name does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property task does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
115
116
            return false;
117
118
        }
119
120
        return $this->manager->isQueued($job);
121
122
    }
123
124
    public function run() {
125
126
        foreach ($this->manager->queued() as $uid => $job) {
127
128
            $this->events->emit( new JobEvent('start', $job) );
129
            $this->events->emit( new JobStatusEvent('start', $job) );
130
131
            if ( $this->multithread === false ) {
132
133
                $pid = ProcessTools::getPid();
134
135
                $this->manager->isStarting($uid, $pid);
136
137
                $result = $this->runner->run(
138
                    $job->name,
139
                    $job->task,
140
                    $job->id,
141
                    $job->parameters
142
                );
143
144
                $this->manager->isCompleted($uid, $result->success, $result->result, $result->wid);
0 ignored issues
show
Documentation introduced by
The property success does not exist on object<Comodojo\Extender\Tasks\Result>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property result does not exist on object<Comodojo\Extender\Tasks\Result>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property wid does not exist on object<Comodojo\Extender\Tasks\Result>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
145
146
                $this->events->emit( new JobEvent('stop', $job) );
147
                $this->events->emit( new JobStatusEvent('stop', $job) );
148
149
                continue;
150
151
            }
152
153
            try {
154
155
                $pid = $this->forker($job);
156
157
            } catch (Exception $e) {
158
159
                $this->manager->isAborted($uid, $e->getMessage());
160
161
                $this->events->emit( new JobEvent('stop', $job) );
162
                $this->events->emit( new JobStatusEvent('stop', $job) );
163
164
                continue;
165
166
            }
167
168
            $this->manager->isStarting($uid, $pid);
169
170
            if ( $this->max_childs > 0 && count($this->manager->running()) >= $this->max_childs ) {
171
172
                while( count($this->manager->running()) >= $this->max_childs ) {
173
174
                    $this->catcher();
175
176
                }
177
178
            }
179
180
            // is it the right way to terminate loop?
181
            // if ( $this->active === false ) return;
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
182
183
        }
184
185
        if ( $this->multithread === true ) $this->catcher_loop();
186
187
        return array_values($this->manager->completed());
188
189
    }
190
191
    public function free() {
192
193
        $this->ipc->free();
194
        $this->manager->free();
195
196
    }
197
198 View Code Duplication
    public function stop() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
200
        $this->logger->info("Stop signal received, trying to termminate jobs gracefully");
201
202
        // $this->active = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
203
204
        $this->abortQueued("Stop signal received, aborting queued jobs");
205
206
        foreach ( $this->manager->running() as $uid => $job ) {
207
208
            $term = ProcessTools::term($job->pid, $this->lagger_timeout);
0 ignored issues
show
Unused Code introduced by
$term is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
209
210
        }
211
212
    }
213
214 View Code Duplication
    public function kill() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
215
216
        $this->logger->info("Term signal received, termminating jobs the hard way");
217
218
        // $this->active = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
219
220
        $this->abortQueued("Kill signal received, aborting queued jobs");
221
222
        foreach ( $this->manager->running() as $uid => $job ) {
223
224
            $term = ProcessTools::kill($job->pid);
0 ignored issues
show
Unused Code introduced by
$term is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
225
226
        }
227
228
    }
229
230
    private function forker(Job $job) {
231
232
        //$this->logger->notice("Starting job ".$job->name."(".$job['id'].")");
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
233
234
        $uid = $job->uid;
0 ignored issues
show
Documentation introduced by
The property uid does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
235
236
        try {
237
238
            $this->ipc->init($uid);
239
240
        } catch (Exception $e) {
241
242
            $this->logger->error("Aborting job ".$job->name.": ".$e->getMessage());
0 ignored issues
show
Documentation introduced by
The property name does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
243
244
            $this->ipc->hang($uid);
245
246
            throw $e;
247
248
        }
249
250
        $pid = pcntl_fork();
251
252
        if ( $pid == -1 ) {
253
254
            // $this->logger->error("Could not fok job, aborting");
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
255
256
            throw new Exception("Unable to fork job, aborting");
257
258
        } elseif ( $pid ) {
259
260
            //PARENT will take actions on processes later
261
262
            $niceness = $job->niceness;
0 ignored issues
show
Documentation introduced by
The property niceness does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
263
264
            if ( $niceness !== null ) ProcessTools::setNiceness($niceness, $pid);
265
266
        } else {
267
268
            $this->ipc->close($uid, Ipc::READER);
269
270
            $result = $this->runner->run(
271
                $job->name,
0 ignored issues
show
Documentation introduced by
The property name does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
272
                $job->task,
0 ignored issues
show
Documentation introduced by
The property task does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
273
                $job->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
274
                $job->parameters
0 ignored issues
show
Documentation introduced by
The property parameters does not exist on object<Comodojo\Extender\Jobs\Job>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
275
            );
276
277
            $output = array(
278
                'success' => $result->success,
0 ignored issues
show
Documentation introduced by
The property success does not exist on object<Comodojo\Extender\Tasks\Result>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
279
                'result' => $result->result,
0 ignored issues
show
Documentation introduced by
The property result does not exist on object<Comodojo\Extender\Tasks\Result>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
280
                'wid' => $result->wid
0 ignored issues
show
Documentation introduced by
The property wid does not exist on object<Comodojo\Extender\Tasks\Result>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
281
            );
282
283
            $this->ipc->write($uid, serialize($output));
284
285
            $this->ipc->close($uid, Ipc::WRITER);
286
287
            exit(!$result->success);
288
289
        }
290
291
        return $pid;
292
293
    }
294
295
    private function catcher_loop() {
296
297
        while ( !empty($this->manager->running()) ) {
298
299
            $this->catcher();
300
301
        }
302
303
    }
304
305
    /**
306
     * Catch results from completed jobs
307
     *
308
     */
309
    private function catcher() {
310
311
        foreach ( $this->manager->running() as $uid => $job ) {
312
313
            if ( ProcessTools::isRunning($job->pid) === false ) {
314
315
                $this->ipc->close($uid, Ipc::WRITER);
316
317
                try {
318
319
                    $raw_output = $this->ipc->read($uid);
320
321
                    $output = unserialize(rtrim($raw_output));
322
323
                    $this->ipc->close($uid, Ipc::READER);
324
325
                    $success = $output["success"];
326
                    $result = $output["result"];
327
                    $wid = $output["wid"];
328
329
                } catch (Exception $e) {
330
331
                    $success = false;
332
                    $result = $e->getMessage();
333
                    $wid = null;
334
335
                    $this->logger->error($result);
336
337
                }
338
339
                $this->manager->isCompleted($uid, $success, $result, $wid);
340
341
                $status = $success ? 'success' : 'error';
342
343
                $this->logger->notice("Job ".$job->name."(id: ".$job->id.", uid: $uid) ends in $status");
344
345
                $this->events->emit( new JobEvent('stop', $job) );
346
                $this->events->emit( new JobStatusEvent('stop', $job) );
347
348
            } else {
349
350
                $current_time = microtime(true);
351
352
                $maxtime = is_null($job->maxtime) ? $this->max_runtime : $job->maxtime;
353
354
                if ( $current_time > $job->start_timestamp + $maxtime ) {
355
356
                    $this->logger->warning("Killing pid ".$job->pid." due to maximum exec time reached", array(
357
                        "START_TIME"    => $job->start_timestamp,
358
                        "CURRENT_TIME"  => $current_time,
359
                        "MAX_RUNTIME"   => $maxtime
360
                    ));
361
362
                    $kill = ProcessTools::term($job->pid, $this->lagger_timeout);
363
364
                    if ( $kill ) {
365
                        $this->logger->warning("Pid ".$job->pid." killed");
366
                    } else {
367
                        $this->logger->warning("Pid ".$job->pid." could not be killed");
368
                    }
369
370
                    $this->ipc->hang($uid);
371
372
                    $this->manager->isCompleted($uid, false, "Job killed due to max runtime reached");
373
374
                    $this->logger->notice("Job ".$job->name."(id: ".$job->id.", uid: $uid) ends in error");
375
376
                    $this->events->emit( new JobEvent('stop', $job) );
377
                    $this->events->emit( new JobStatusEvent('stop', $job) );
378
379
                }
380
381
            }
382
383
        }
384
385
    }
386
387
    private function abortQueued($message) {
388
389
        foreach ($this->manager->queued() as $uid => $job) {
390
391
            $this->manager->isAborted($uid, $message);
392
393
        }
394
395
    }
396
397
}
398