Loop::setStatus()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php namespace Comodojo\Daemon\Worker;
2
3
use \Comodojo\Daemon\Events\WorkerEvent;
4
use \Comodojo\Foundation\Validation\DataFilter;
5
use \Psr\Log\LoggerInterface;
6
use \Countable;
7
use \Exception;
8
9
/**
10
 * @package     Comodojo Daemon
11
 * @author      Marco Giovinazzi <[email protected]>
12
 * @license     MIT
13
 *
14
 * LICENSE:
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
25
class Loop implements Countable {
26
27
    const SPINUP = 0;
28
    const LOOPING = 1;
29
    const PAUSED = 2;
30
    const SPINDOWN = 3;
31
32
    private $active = 1;
33
34
    private $paused;
35
36
    private $status;
37
38
    private $count = 0;
39
40
    private $looptime = 1;
41
42
    private $events;
43
44
    private $worker;
45
46
    public function __construct(Worker $worker) {
47
48
        $this->worker = $worker;
49
50
        $this->events = $worker->getInstance()->getEvents();
51
52
        $this->looptime = DataFilter::filterInteger($worker->getLooptime(), $min = 1, $max = PHP_INT_MAX, $default = 1);
0 ignored issues
show
Bug introduced by
$min = 1 of type integer is incompatible with the type array expected by parameter $min of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

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

52
        $this->looptime = DataFilter::filterInteger($worker->getLooptime(), /** @scrutinizer ignore-type */ $min = 1, $max = PHP_INT_MAX, $default = 1);
Loading history...
Bug introduced by
$default = 1 of type integer is incompatible with the type array expected by parameter $default of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

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

52
        $this->looptime = DataFilter::filterInteger($worker->getLooptime(), $min = 1, $max = PHP_INT_MAX, /** @scrutinizer ignore-type */ $default = 1);
Loading history...
Bug introduced by
$max = Comodojo\Daemon\Worker\PHP_INT_MAX of type integer is incompatible with the type array expected by parameter $max of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

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

52
        $this->looptime = DataFilter::filterInteger($worker->getLooptime(), $min = 1, /** @scrutinizer ignore-type */ $max = PHP_INT_MAX, $default = 1);
Loading history...
53
54
        $this->events->subscribe('daemon.worker.stop', '\Comodojo\Daemon\Listeners\StopWorker');
55
        $this->events->subscribe('daemon.worker.pause', '\Comodojo\Daemon\Listeners\PauseWorker');
56
        $this->events->subscribe('daemon.worker.resume', '\Comodojo\Daemon\Listeners\ResumeWorker');
57
58
        register_tick_function([$this, 'ticker']);
59
60
    }
61
62
    public function start() {
63
64
        declare(ticks=5);
65
66
        if ( $this->status !== null ) {
67
            throw new Exception("Already looping");
68
        }
69
70
        // spinup daemon
71
        $this->setStatus(self::SPINUP);
72
        $this->worker->getInstance()->spinup();
73
74
        // start looping
75
        $this->setStatus(self::LOOPING);
76
        while ( $this->active ) {
77
78
            if ( $this->paused ) {
79
                $this->setStatus(self::PAUSED);
80
                sleep($this->looptime);
81
                continue;
82
            }
83
84
            $this->setStatus(self::LOOPING);
85
86
            $start = microtime(true);
87
88
            $this->events->emit(new WorkerEvent('loopstart', $this, $this->worker));
89
90
            $this->worker->getInstance()->loop();
91
92
            ++$this->count;
93
94
            $elapsed = (microtime(true) - $start);
95
96
            $this->events->emit(new WorkerEvent('loopstop', $this, $this->worker));
97
98
            $lefttime = $this->looptime - $elapsed;
99
100
            if ( $lefttime > 0 ) usleep($lefttime * 1000000);
101
102
        }
103
104
        $this->setStatus(self::SPINDOWN);
105
106
        // spindown worker
107
        $this->worker->getInstance()->spindown();
108
109
        return;
110
111
    }
112
113
    public function stop() {
114
115
        $this->active = false;
116
117
    }
118
119
    public function pause() {
120
121
        $this->paused = true;
122
123
    }
124
125
    public function resume() {
126
127
        $this->paused = false;
128
129
    }
130
131
    public function count() {
132
133
        return $this->count;
134
135
    }
136
137
    public function ticker() {
138
139
        $signal = $this->worker->getOutputChannel()->read();
140
141
        if ( !empty($signal) ) {
142
            $this->events->emit(new WorkerEvent($signal, $this, $this->worker));
143
            $this->worker->getOutputChannel()->delete();
144
        }
145
146
    }
147
148
    private function setStatus($status) {
149
        $this->status = $status;
150
        return $this->worker->getInputChannel()->send($status);
151
    }
152
153
}
154