Resources::startup()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Cluster resources manager
4
 * User: moyo
5
 * Date: 27/10/2017
6
 * Time: 2:48 PM
7
 */
8
9
namespace Carno\Cluster;
10
11
use Carno\Cluster\Chips\InitializeTips;
12
use Carno\Cluster\Classify\Classified;
13
use function Carno\Coroutine\all;
14
use Carno\Promise\Promise;
15
use Carno\Promise\Promised;
16
17
class Resources
18
{
19
    use InitializeTips;
20
21
    /**
22
     * @var Classified
23
     */
24
    private $classify = null;
25
26
    /**
27
     * @var bool
28
     */
29
    private $started = false;
30
31
    /**
32
     * @var array
33
     */
34
    private $paused = [];
35
36
    /**
37
     * @var array
38
     */
39
    private $loaded = [];
40
41
    /**
42
     * @var Promised[]
43
     */
44
    private $waits = [];
45
46
    /**
47
     * Resources constructor.
48
     * @param Classified $classify
49
     */
50
    public function __construct(Classified $classify)
51
    {
52
        $this->classify = $classify;
53
    }
54
55
    /**
56
     * @return static
57
     */
58
    public function startup() : self
59
    {
60
        $this->started = true;
61
        while ($this->paused) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->paused of type array 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...
62
            $this->initialize(...array_shift($this->paused));
63
        }
64
        return $this;
65
    }
66
67
    /**
68
     * @param string $scene
69
     * @param string $group
70
     * @param string $server
71
     * @param Managed $managed
72
     */
73
    public function initialize(string $scene, string $group, string $server, Managed $managed) : void
74
    {
75
        if (!$this->started) {
76
            $this->paused[] = func_get_args();
77
            return;
78
        }
79
80
        if (isset($this->loaded[$sk = $this->sk($group, $server)])) {
81
            return;
82
        }
83
84
        $this->waits[$sk] = $wait = $this->classify->discovery($scene)->attach($group, $server, $managed);
85
86
        $wait->then(function () use ($sk) {
87
            unset($this->waits[$sk]);
88
        });
89
90
        $this->loaded[$sk] = [$scene, $group, $server];
91
92
        $this->waiting($sk, $managed);
93
    }
94
95
    /**
96
     * @return Promised
97
     */
98
    public function ready() : Promised
99
    {
100
        return all(...array_values($this->waits));
101
    }
102
103
    /**
104
     * @param string $group
105
     * @param string $server
106
     * @return Promised
107
     */
108
    public function forget(string $group, string $server) : Promised
109
    {
110
        if (is_null($gss = $this->loaded[$sk = $this->sk($group, $server)] ?? null)) {
111
            return Promise::rejected();
112
        }
113
114
        unset($this->loaded[$sk]);
115
116
        return $this->classify->discovery(array_shift($gss))->detach(...$gss);
0 ignored issues
show
Bug introduced by
The call to Carno\Cluster\Discovery\Discovered::detach() has too few arguments starting with server. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
        return $this->classify->discovery(array_shift($gss))->/** @scrutinizer ignore-call */ detach(...$gss);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
117
    }
118
119
    /**
120
     * @return Promised
121
     */
122
    public function release() : Promised
123
    {
124
        $pending = [];
125
126
        foreach ($this->loaded as $sk => $gss) {
127
            unset($this->loaded[$sk]);
128
            $pending[] = $this->classify->discovery(array_shift($gss))->detach(...$gss);
0 ignored issues
show
Bug introduced by
The call to Carno\Cluster\Discovery\Discovered::detach() has too few arguments starting with server. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

128
            $pending[] = $this->classify->discovery(array_shift($gss))->/** @scrutinizer ignore-call */ detach(...$gss);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
129
        }
130
131
        return all(...$pending);
132
    }
133
134
    /**
135
     * @param string $group
136
     * @param string $server
137
     * @return string
138
     */
139
    private function sk(string $group, string $server) : string
140
    {
141
        return sprintf('%s:%s', $group ?: 'service', $server);
142
    }
143
}
144