Delayer::isEmpty()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace mpyw\Co\Internal;
4
use React\Promise\Deferred;
5
use React\Promise\PromiseInterface;
6
7
class Delayer
8
{
9
    /**
10
     * Delays to be ended at.
11
     * @var array
12
     */
13
    private $untils = [];
14
15
    /**
16
     * Deferreds.
17
     * @var array
18
     */
19
    private $deferreds = [];
20
21
    /**
22
     * Add delay.
23
     * @param int $time
24
     * @return PromiseInterface
25
     */
26 6
    public function add($time)
27 6
    {
28 6
        $deferred = new Deferred;
29 6
        $time = filter_var($time, FILTER_VALIDATE_FLOAT);
30 6
        if ($time === false) {
31 1
            throw new \InvalidArgumentException('Delay must be number.');
32
        }
33 5
        if ($time < 0) {
34 1
            throw new \DomainException('Delay must be positive.');
35
        }
36
        do {
37 4
            $id = uniqid();
38 4
        } while (isset($this->untils[$id]));
39 4
        $this->untils[$id] = microtime(true) + $time;
40 4
        $this->deferreds[$id] = $deferred;
41 4
        return $deferred->promise();
42
    }
43
44
    /**
45
     * Sleep at least required.
46
     */
47 18
    public function sleep()
48 18
    {
49 18
        $now = microtime(true);
50 18
        $min = null;
51 18
        foreach ($this->untils as $id => $until) {
52 4
            $diff = $until - $now;
53 4
            if ($diff < 0) {
54
                // @codeCoverageIgnoreStart
55
                return;
56
                // @codeCoverageIgnoreEnd
57
            }
58 4
            if ($min !== null && $diff >= $min) {
59 2
                continue;
60
            }
61 4
            $min = $diff;
62
        }
63 18
        $min && usleep($min * 1000000);
64 18
    }
65
66
    /**
67
     * Consume delay queue.
68
     */
69 33
    public function consume()
70 33
    {
71 33
        foreach ($this->untils as $id => $until) {
72 4
            $diff = $until - microtime(true);
73 4
            if ($diff > 0.0 || !isset($this->deferreds[$id])) {
74 2
                continue;
75
            }
76 4
            $deferred = $this->deferreds[$id];
77 4
            unset($this->deferreds[$id], $this->untils[$id]);
78 4
            $deferred->resolve(null);
79
        }
80 33
    }
81
82
    /**
83
     * Is $untils empty?
84
     * @return bool
85
     */
86 23
    public function isEmpty()
87 23
    {
88 23
        return !$this->untils;
89
    }
90
}
91