Completed
Push — master ( e2ef70...127eb9 )
by Ryosuke
03:24
created

Delayer::consumeAndResolve()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 10
cts 10
cp 1
rs 9.2
cc 4
eloc 8
nc 3
nop 0
crap 4
1
<?php
2
3
namespace mpyw\Co\Internal;
4
use mpyw\Co\Co;
5
use mpyw\Co\Internal\CoOption;
6
use mpyw\Co\CURLException;
7
use mpyw\RuntimePromise\Deferred;
8
9
class Delayer
10
{
11
    /**
12
     * Delays to be ended at.
13
     * @var array
14
     */
15
    private $untils = [];
16
17
    /**
18
     * React Deferreds.
19
     * @var Deferred
20
     */
21
    private $deferreds = [];
22
23
    /**
24
     * Add delay.
25
     * @param int      $time
26
     * @param Deferred $deferred
27
     */
28 6
    public function add($time, Deferred $deferred)
29 6
    {
30 6
        $time = filter_var($time, FILTER_VALIDATE_FLOAT);
31 6
        if ($time === false) {
32 1
            throw new \InvalidArgumentException('Delay must be number.');
33
        }
34 5
        if ($time < 0) {
35 1
            throw new \DomainException('Delay must be positive.');
36
        }
37
        do {
38 4
            $id = uniqid();
39 4
        } while (isset($this->untils[$id]));
40 4
        $this->untils[$id] = microtime(true) + $time;
41 4
        $this->deferreds[$id] = $deferred;
42 4
    }
43
44
    /**
45
     * Sleep at least required.
46
     */
47 9
    public function sleep()
48 9
    {
49 9
        $now = microtime(true);
50 9
        $min = null;
51 9
        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 9
        $min && usleep($min * 1000000);
64 9
    }
65
66
    /**
67
     * Consume delay queue.
68
     */
69 18
    public function consumeAndResolve()
70 18
    {
71 18
        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 18
    }
81
82
    /**
83
     * Is $untils empty?
84
     * @return bool
85
     */
86
    public function empty()
87
    {
88
        return !$this->untils;
89
    }
90
}
91