AbstractEndpointsLister   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 31
dl 0
loc 96
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A distinctID() 0 10 3
A result() 0 36 4
A service() 0 6 1
1
<?php
2
/**
3
 * Common service endpoints lister
4
 * User: moyo
5
 * Date: 20/11/2017
6
 * Time: 6:20 PM
7
 */
8
9
namespace Carno\Consul\APIs;
10
11
use Carno\Consul\Contracts\Defaults;
12
use Carno\Consul\Types\Service;
13
use function Carno\Coroutine\msleep;
14
use Carno\HTTP\Standard\Response;
15
use Carno\Net\Address;
16
use Carno\Net\Endpoint;
17
use Carno\Promise\Promised;
18
19
abstract class AbstractEndpointsLister extends AbstractWatcher
20
{
21
    /**
22
     * @var string
23
     */
24
    protected $method = 'GET';
25
26
    /**
27
     * @var Service
28
     */
29
    private $service = null;
30
31
    /**
32
     * @param string $service
33
     * @return static
34
     */
35
    public function service(string $service) : self
36
    {
37
        $this->service = new Service($service);
38
        $this->setVars('service', $service);
39
        $this->addParams();
40
        return $this;
41
    }
42
43
    /**
44
     * @return Promised|Service
45
     */
46
    public function result()
47
    {
48
        return $this->perform($this->getCanceller())->then(function (Response $response) {
49
            if ($response->getStatusCode() !== 200) {
50
                goto DO_WAIT;
51
            }
52
53
            // reset endpoints
54
            $this->service->setEndpoints();
55
56
            // reset version
57
            $this->assignVIndex($this->service, $response);
58
            $this->setVIndex($this->service->getVersion());
59
60
            // new endpoints
61
            $endpoints = $this->decodeResponse((string)$response->getBody());
62
            foreach ($endpoints as $endpoint) {
63
                list($id, $name, $host, $port, $tags) = $this->genInfo($endpoint);
64
                $this->service->addEndpoint(
65
                    (new Endpoint(new Address($host, $port)))
66
                        ->relatedService($name)
67
                        ->assignID($this->distinctID($name, $id))
68
                        ->setTags(...$tags)
69
                );
70
            }
71
72
            // continue to next
73
            if ($this->service->hasVersion()) {
74
                return $this->service;
75
            }
76
77
            DO_WAIT:
78
79
            // make sleep if no versions
80
            return msleep(rand(...$this->emptyWait), function () {
0 ignored issues
show
Bug introduced by
$this->emptyWait is expanded, but the parameter $min of rand() does not expect variable arguments. ( Ignorable by Annotation )

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

80
            return msleep(rand(/** @scrutinizer ignore-type */ ...$this->emptyWait), function () {
Loading history...
81
                return $this->service;
82
            });
83
        });
84
    }
85
86
    /**
87
     * @param string $service
88
     * @param string $id
89
     * @return string
90
     */
91
    private function distinctID(string $service, string $id) : string
92
    {
93
        $id = ltrim($id, sprintf('%s:', Defaults::SVC_FLAG));
94
        if (substr($id, 0, strlen($service)) === $service) {
95
            $id = substr($id, strlen($service));
96
            if (substr($id, 0, 1) === '-') {
97
                $id = substr($id, 1);
98
            }
99
        }
100
        return $id;
101
    }
102
103
    /**
104
     * returned syntax
105
     * [string $id, string $name, string $host, int $port, array $tags]
106
     * @param array $endpoint
107
     * @return array
108
     */
109
    abstract protected function genInfo(array $endpoint) : array;
110
111
    /**
112
     * triggered when service assigned
113
     */
114
    abstract protected function addParams() : void;
115
}
116