GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#111)
by Alexander
01:47
created

Pool::withBinary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\Async;
4
5
use ArrayAccess;
6
use InvalidArgumentException;
7
use Spatie\Async\Process\ParallelProcess;
8
use Spatie\Async\Process\Runnable;
9
use Spatie\Async\Process\SynchronousProcess;
10
use Spatie\Async\Runtime\ParentRuntime;
11
12
class Pool implements ArrayAccess
13
{
14
    public static $forceSynchronous = false;
15
16
    protected $concurrency = 20;
17
    protected $tasksPerProcess = 1;
18
    protected $timeout = 300;
19
    protected $sleepTime = 50000;
20
21
    /** @var \Spatie\Async\Process\Runnable[] */
22
    protected $queue = [];
23
24
    /** @var \Spatie\Async\Process\Runnable[] */
25
    protected $inProgress = [];
26
27
    /** @var \Spatie\Async\Process\Runnable[] */
28
    protected $finished = [];
29
30
    /** @var \Spatie\Async\Process\Runnable[] */
31
    protected $failed = [];
32
33
    /** @var \Spatie\Async\Process\Runnable[] */
34
    protected $timeouts = [];
35
36
    protected $results = [];
37
38
    protected $status;
39
40
    protected $stopped = false;
41
42
    protected $binary = 'php';
43
44
    public function __construct()
45
    {
46
        if (static::isSupported()) {
47
            $this->registerListener();
48
        }
49
50
        $this->status = new PoolStatus($this);
51
    }
52
53
    /**
54
     * @return static
55
     */
56
    public static function create()
57
    {
58
        return new static();
59
    }
60
61
    public static function isSupported(): bool
62
    {
63
        return
64
            function_exists('pcntl_async_signals')
65
            && function_exists('posix_kill')
66
            && ! self::$forceSynchronous;
67
    }
68
69
    public function concurrency(int $concurrency): self
70
    {
71
        $this->concurrency = $concurrency;
72
73
        return $this;
74
    }
75
76
    public function timeout(float $timeout): self
77
    {
78
        $this->timeout = $timeout;
0 ignored issues
show
Documentation Bug introduced by
The property $timeout was declared of type integer, but $timeout is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
79
80
        return $this;
81
    }
82
83
    public function withBinary(string $binary = 'php'): self
84
    {
85
        $this->binary = $binary;
86
87
        return $this;
88
    }
89
90
    public function autoload(string $autoloader): self
91
    {
92
        ParentRuntime::init($autoloader);
93
94
        return $this;
95
    }
96
97
    public function sleepTime(int $sleepTime): self
98
    {
99
        $this->sleepTime = $sleepTime;
100
101
        return $this;
102
    }
103
104
    public function notify()
105
    {
106
        if (count($this->inProgress) >= $this->concurrency) {
107
            return;
108
        }
109
110
        $process = array_shift($this->queue);
111
112
        if (! $process) {
113
            return;
114
        }
115
116
        $this->putInProgress($process);
117
    }
118
119
    /**
120
     * @param \Spatie\Async\Process\Runnable|callable $process
121
     * @param int|null $outputLength
122
     *
123
     * @return \Spatie\Async\Process\Runnable
124
     */
125
    public function add($process, ?int $outputLength = null): Runnable
126
    {
127
        if (! is_callable($process) && ! $process instanceof Runnable) {
128
            throw new InvalidArgumentException('The process passed to Pool::add should be callable.');
129
        }
130
131
        if (! $process instanceof Runnable) {
132
            $process = ParentRuntime::createProcess($process, $outputLength, $this->binary);
133
        }
134
135
        $this->putInQueue($process);
136
137
        return $process;
138
    }
139
140
    public function wait(?callable $intermediateCallback = null): array
141
    {
142
        while ($this->inProgress) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->inProgress of type Spatie\Async\Process\Runnable[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
143
            foreach ($this->inProgress as $process) {
144
                if ($process->getCurrentExecutionTime() > $this->timeout) {
145
                    $this->markAsTimedOut($process);
146
                }
147
148
                if ($process instanceof SynchronousProcess) {
149
                    $this->markAsFinished($process);
150
                }
151
            }
152
153
            if (! $this->inProgress) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->inProgress of type Spatie\Async\Process\Runnable[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
154
                break;
155
            }
156
157
            if ($intermediateCallback) {
158
                call_user_func_array($intermediateCallback, [$this]);
159
            }
160
161
            usleep($this->sleepTime);
162
        }
163
164
        return $this->results;
165
    }
166
167
    public function putInQueue(Runnable $process)
168
    {
169
        $this->queue[$process->getId()] = $process;
170
171
        $this->notify();
172
    }
173
174
    public function putInProgress(Runnable $process)
175
    {
176
        if ($this->stopped) {
177
            return;
178
        }
179
180
        if ($process instanceof ParallelProcess) {
181
            $process->getProcess()->setTimeout($this->timeout);
182
        }
183
184
        $process->start();
185
186
        unset($this->queue[$process->getId()]);
187
188
        $this->inProgress[$process->getPid()] = $process;
189
    }
190
191
    public function markAsFinished(Runnable $process)
192
    {
193
        unset($this->inProgress[$process->getPid()]);
194
195
        $this->notify();
196
197
        $this->results[] = $process->triggerSuccess();
198
199
        $this->finished[$process->getPid()] = $process;
200
    }
201
202
    public function markAsTimedOut(Runnable $process)
203
    {
204
        unset($this->inProgress[$process->getPid()]);
205
206
        $this->notify();
207
208
        $process->triggerTimeout();
209
210
        $this->timeouts[$process->getPid()] = $process;
211
    }
212
213
    public function markAsFailed(Runnable $process)
214
    {
215
        unset($this->inProgress[$process->getPid()]);
216
217
        $this->notify();
218
219
        $process->triggerError();
220
221
        $this->failed[$process->getPid()] = $process;
222
    }
223
224
    public function offsetExists($offset)
225
    {
226
        // TODO
227
228
        return false;
229
    }
230
231
    public function offsetGet($offset)
232
    {
233
        // TODO
234
    }
235
236
    public function offsetSet($offset, $value)
237
    {
238
        $this->add($value);
239
    }
240
241
    public function offsetUnset($offset)
242
    {
243
        // TODO
244
    }
245
246
    /**
247
     * @return \Spatie\Async\Process\Runnable[]
248
     */
249
    public function getQueue(): array
250
    {
251
        return $this->queue;
252
    }
253
254
    /**
255
     * @return \Spatie\Async\Process\Runnable[]
256
     */
257
    public function getInProgress(): array
258
    {
259
        return $this->inProgress;
260
    }
261
262
    /**
263
     * @return \Spatie\Async\Process\Runnable[]
264
     */
265
    public function getFinished(): array
266
    {
267
        return $this->finished;
268
    }
269
270
    /**
271
     * @return \Spatie\Async\Process\Runnable[]
272
     */
273
    public function getFailed(): array
274
    {
275
        return $this->failed;
276
    }
277
278
    /**
279
     * @return \Spatie\Async\Process\Runnable[]
280
     */
281
    public function getTimeouts(): array
282
    {
283
        return $this->timeouts;
284
    }
285
286
    public function status(): PoolStatus
287
    {
288
        return $this->status;
289
    }
290
291
    protected function registerListener()
292
    {
293
        pcntl_async_signals(true);
294
295
        pcntl_signal(SIGCHLD, function ($signo, $status) {
296
            while (true) {
297
                $pid = pcntl_waitpid(-1, $processState, WNOHANG | WUNTRACED);
298
299
                if ($pid <= 0) {
300
                    break;
301
                }
302
303
                $process = $this->inProgress[$pid] ?? null;
304
305
                if (! $process) {
306
                    continue;
307
                }
308
309
                if ($status['status'] === 0) {
310
                    $this->markAsFinished($process);
311
312
                    continue;
313
                }
314
315
                $this->markAsFailed($process);
316
            }
317
        });
318
    }
319
320
    public function stop()
321
    {
322
        $this->stopped = true;
323
    }
324
}
325