Passed
Push — master ( c649ab...71b580 )
by Harry
02:19
created

Run::start()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 14
cts 14
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 12
nc 2
nop 0
crap 5
1
<?php
2
3
namespace Graze\ParallelProcess;
4
5
use Symfony\Component\Process\Process;
6
7
class Run implements RunInterface
8
{
9
    const ON_SUCCESS  = 1;
10
    const ON_FAILURE  = 2;
11
    const ON_PROGRESS = 3;
12
13
    /** @var Process */
14
    private $process;
15
    /** @var callable|null */
16
    private $onSuccess;
17
    /** @var callable|null */
18
    private $onFailure;
19
    /** @var callable|null */
20
    private $onProgress;
21
    /** @var callable|null */
22
    private $onStart;
23
    /** @var float */
24
    private $started;
25
    /** @var bool */
26
    private $successful = false;
27
    /** @var bool */
28
    private $completed = false;
29
    /** @var string */
30
    private $last = '';
31
    /** @var string */
32
    private $lastType = 'std';
33
    /** @var bool */
34
    private $updateOnPoll = true;
35
    /** @var bool */
36
    private $updateOnProcessOutput = true;
37
38
    /**
39
     * Run constructor.
40
     *
41
     * @param Process       $process
42
     * @param callable|null $onSuccess  When the process finishes and is successful
43
     *                                  function (Process $process, float $duration, string $last, string $lastType) :
44
     *                                  void
45
     * @param callable|null $onFailure  When the process finishes and failed
46
     *                                  function (Process $process, float $duration, string $last, string $lastType) :
47
     *                                  void
48
     * @param callable|null $onProgress Called every check period or a message is returned from the process
49
     *                                  function (Process $process, float $duration, string $last, string $lastType) :
50
     *                                  void
51
     * @param callable|null $onStart    When the process starts
52
     *                                  function (Process $process, float $duration, string $last, string $lastType) :
53
     *                                  void
54
     */
55 44
    public function __construct(
56
        Process $process,
57
        callable $onSuccess = null,
58
        callable $onFailure = null,
59
        callable $onProgress = null,
60
        callable $onStart = null
61
    ) {
62 44
        $this->process = $process;
63 44
        $this->onSuccess = $onSuccess;
64 44
        $this->onFailure = $onFailure;
65 44
        $this->onProgress = $onProgress;
66 44
        $this->onStart = $onStart;
67 44
    }
68
69
    /**
70
     * Start the process
71
     *
72
     * @return $this
73
     */
74 37
    public function start()
75
    {
76 37
        if (!$this->process->isRunning()) {
77 36
            $this->started = microtime(true);
78 36
            $this->update($this->onStart);
79 36
            $this->process->start(
80 36
                function ($type, $data) {
81 19
                    $this->lastType = $type;
82 19
                    foreach (explode("\n", $data) as $line) {
83 19
                        $this->last = rtrim($line);
84 19
                        if (mb_strlen($this->last) > 0 && $this->updateOnProcessOutput) {
85 19
                            $this->update($this->onProgress);
86
                        }
87
                    }
88 36
                }
89
            );
90 36
            $this->completed = false;
91
        }
92
93 37
        return $this;
94
    }
95
96
    /**
97
     * Poll the process to see if it is still running, and trigger events
98
     *
99
     * @return bool true if the process is currently running (started and not terminated)
100
     */
101 34
    public function poll()
102
    {
103 34
        if ($this->completed || !$this->hasStarted()) {
104 1
            return false;
105
        }
106
107 33
        if ($this->process->isRunning()) {
108 24
            if ($this->updateOnPoll) {
109 17
                $this->update($this->onProgress);
110
            }
111 24
            return true;
112
        }
113
114 33
        $this->completed = true;
115
116 33
        if ($this->process->isSuccessful()) {
117 24
            $this->successful = true;
118 24
            $this->update($this->onSuccess);
119
        } else {
120 10
            $this->update($this->onFailure);
121
        }
122 33
        return false;
123
    }
124
125
    /**
126
     * Return if the underlying process is running
127
     *
128
     * @return bool
129
     */
130 32
    public function isRunning()
131
    {
132 32
        return $this->process->isRunning();
133
    }
134
135
    /**
136
     * Call an event callback
137
     *
138
     * @param callable|null $func
139
     */
140 36
    protected function update($func)
141
    {
142 36
        if (!is_null($func)) {
143 30
            call_user_func(
144 30
                $func,
145 30
                $this->process,
146 30
                microtime(true) - $this->started,
147 30
                $this->last,
148 30
                $this->lastType
149
            );
150
        }
151 36
    }
152
153
    /**
154
     * @return bool
155
     */
156 28
    public function isSuccessful()
157
    {
158 28
        return $this->successful;
159
    }
160
161
    /**
162
     * @return bool
163
     */
164 37
    public function hasStarted()
165
    {
166 37
        return $this->process->isStarted();
167
    }
168
169
    /**
170
     * @return Process
171
     */
172 3
    public function getProcess()
173
    {
174 3
        return $this->process;
175
    }
176
177
    /**
178
     * @param bool $updateOnPoll
179
     *
180
     * @return $this
181
     */
182 8
    public function setUpdateOnPoll($updateOnPoll)
183
    {
184 8
        $this->updateOnPoll = $updateOnPoll;
185 8
        return $this;
186
    }
187
188
    /**
189
     * @return bool
190
     */
191 2
    public function isUpdateOnPoll()
192
    {
193 2
        return $this->updateOnPoll;
194
    }
195
196
    /**
197
     * @param bool $update
198
     *
199
     * @return $this
200
     */
201 14
    public function setUpdateOnProcessOutput($update)
202
    {
203 14
        $this->updateOnProcessOutput = $update;
204 14
        return $this;
205
    }
206
207
    /**
208
     * @return bool
209
     */
210 2
    public function isUpdateOnProcessOutput()
211
    {
212 2
        return $this->updateOnProcessOutput;
213
    }
214
}
215