Completed
Push — master ( 52b1c2...7b34df )
by Tobias
02:29
created

HttpClientPoolItem   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 98.04%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 16
lcom 1
cbo 3
dl 0
loc 161
ccs 50
cts 51
cp 0.9804
rs 10
c 1
b 1
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A sendRequest() 0 19 3
A sendAsyncRequest() 0 19 2
A isDisabled() 0 19 4
A getSendingRequestCount() 0 4 1
A getDisabledAt() 0 4 1
A incrementRequestCount() 0 4 1
A decrementRequestCount() 0 4 1
A enable() 0 4 1
A disable() 0 4 1
1
<?php
2
3
namespace Http\Client\Common;
4
5
use Http\Client\HttpAsyncClient;
6
use Http\Client\HttpClient;
7
use Psr\Http\Message\RequestInterface;
8
use Http\Client\Exception;
9
10
/**
11
 * A HttpClientPoolItem represent a HttpClient inside a Pool.
12
 *
13
 * It is disabled when a request failed and can be reenable after a certain number of seconds
14
 * It also keep tracks of the current number of request the client is currently sending (only usable for async method)
15
 *
16
 * @author Joel Wurtz <[email protected]>
17
 */
18
class HttpClientPoolItem implements HttpClient, HttpAsyncClient
19
{
20
    /**
21
     * @var int Number of request this client is currently sending
22
     */
23
    private $sendingRequestCount = 0;
24
25
    /**
26
     * @var \DateTime|null Time when this client has been disabled or null if enable
27
     */
28
    private $disabledAt;
29
30
    /**
31
     * @var int|null Number of seconds after this client is reenable, by default null: never reenable this client
32
     */
33
    private $reenableAfter;
34
35
    /**
36
     * @var FlexibleHttpClient A http client responding to async and sync request
37
     */
38
    private $client;
39
40
    /**
41
     * @param HttpClient|HttpAsyncClient $client
42
     * @param null|int                   $reenableAfter Number of seconds after this client is reenable
43
     */
44 23
    public function __construct($client, $reenableAfter = null)
45
    {
46 23
        $this->client = new FlexibleHttpClient($client);
47 23
        $this->reenableAfter = $reenableAfter;
48 23
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 13
    public function sendRequest(RequestInterface $request)
54
    {
55 13
        if ($this->isDisabled()) {
56 1
            throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
57
        }
58
59
        try {
60 13
            $this->incrementRequestCount();
61 13
            $response = $this->client->sendRequest($request);
62 5
            $this->decrementRequestCount();
63 13
        } catch (Exception $e) {
64 8
            $this->disable();
65 8
            $this->decrementRequestCount();
66
67 8
            throw $e;
68
        }
69
70 5
        return $response;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 8
    public function sendAsyncRequest(RequestInterface $request)
77
    {
78 8
        if ($this->isDisabled()) {
79 1
            throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
80
        }
81
82 8
        $this->incrementRequestCount();
83
84
        return $this->client->sendAsyncRequest($request)->then(function ($response) {
85 1
            $this->decrementRequestCount();
86
87 1
            return $response;
88 8
        }, function ($exception) {
89 2
            $this->disable();
90 2
            $this->decrementRequestCount();
91
92 2
            throw $exception;
93 8
        });
94
    }
95
96
    /**
97
     * Whether this client is disabled or not.
98
     *
99
     * Will also reactivate this client if possible
100
     *
101
     * @internal
102
     *
103
     * @return bool
104
     */
105 21
    public function isDisabled()
106
    {
107 21
        $disabledAt = $this->getDisabledAt();
108
109 21
        if (null !== $this->reenableAfter && null !== $disabledAt) {
110
            // Reenable after a certain time
111 5
            $now = new \DateTime();
112
113 5
            if (($now->getTimestamp() - $disabledAt->getTimestamp()) >= $this->reenableAfter) {
114 5
                $this->enable();
115
116 5
                return false;
117
            }
118
119
            return true;
120
        }
121
122 21
        return null !== $disabledAt;
123
    }
124
125
    /**
126
     * Get current number of request that is send by the underlying http client.
127
     *
128
     * @internal
129
     *
130
     * @return int
131
     */
132 2
    public function getSendingRequestCount()
133
    {
134 2
        return $this->sendingRequestCount;
135
    }
136
137
    /**
138
     * Return when this client has been disabled or null if it's enabled.
139
     *
140
     * @return \DateTime|null
141
     */
142 21
    private function getDisabledAt()
143
    {
144 21
        return $this->disabledAt;
145
    }
146
147
    /**
148
     * Increment the request count.
149
     */
150 21
    private function incrementRequestCount()
151
    {
152 21
        ++$this->sendingRequestCount;
153 21
    }
154
155
    /**
156
     * Decrement the request count.
157
     */
158 16
    private function decrementRequestCount()
159
    {
160 16
        --$this->sendingRequestCount;
161 16
    }
162
163
    /**
164
     * Enable the current client.
165
     */
166 5
    private function enable()
167
    {
168 5
        $this->disabledAt = null;
169 5
    }
170
171
    /**
172
     * Disable the current client.
173
     */
174 10
    private function disable()
175
    {
176 10
        $this->disabledAt = new \DateTime('now');
177 10
    }
178
}
179