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

Delayer   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 15
c 0
b 0
f 0
lcom 1
cbo 0
dl 0
loc 82
ccs 34
cts 34
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A add() 0 15 4
B sleep() 0 18 6
A consumeAndResolve() 0 12 4
A empty() 0 4 1
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