SignalLoop::__construct()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 8
nop 1
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Queue\Cli;
6
7
class SignalLoop implements LoopInterface
8
{
9
    use SoftLimitTrait;
10
11
    /**
12
     * @psalm-suppress UndefinedConstant
13
     * @psalm-suppress MissingClassConstType
14
     */
15
    protected const SIGNALS_EXIT = [SIGHUP, SIGINT, SIGTERM];
16
    /**
17
     * @psalm-suppress UndefinedConstant
18
     * @psalm-suppress MissingClassConstType
19
     */
20
    protected const SIGNALS_SUSPEND = [SIGTSTP];
21
    /**
22
     * @psalm-suppress UndefinedConstant
23
     * @psalm-suppress MissingClassConstType
24
     */
25
    protected const SIGNALS_RESUME = [SIGCONT];
26
    protected bool $pause = false;
27
    protected bool $exit = false;
28
29
    /**
30
     * @param int $memorySoftLimit Soft RAM limit in bytes. The loop won't let you continue to execute the program if
31
     *     soft limit is reached. Zero means no limit.
32
     */
33 1
    public function __construct(protected int $memorySoftLimit = 0)
34
    {
35 1
        foreach (self::SIGNALS_EXIT as $signal) {
36 1
            pcntl_signal($signal, fn () => $this->exit = true);
37
        }
38 1
        foreach (self::SIGNALS_SUSPEND as $signal) {
39 1
            pcntl_signal($signal, fn () => $this->pause = true);
40
        }
41 1
        foreach (self::SIGNALS_RESUME as $signal) {
42 1
            pcntl_signal($signal, fn () => $this->pause = false);
43
        }
44
    }
45
46
    /**
47
     * Checks signals state.
48
     *
49
     * {@inheritdoc}
50
     */
51 1
    public function canContinue(): bool
52
    {
53 1
        if ($this->memoryLimitReached()) {
54
            return false;
55
        }
56
57 1
        return $this->dispatchSignals();
58
    }
59
60 1
    protected function dispatchSignals(): bool
61
    {
62 1
        pcntl_signal_dispatch();
63
64
        // Wait for resume signal until loop is suspended
65 1
        while ($this->pause && !$this->exit) {
66
            usleep(10000);
67
            pcntl_signal_dispatch();
68
        }
69
70 1
        return !$this->exit;
71
    }
72
73 1
    protected function getMemoryLimit(): int
74
    {
75 1
        return $this->memorySoftLimit;
76
    }
77
}
78