Completed
Pull Request — master (#25)
by Joel
04:45
created

HttpClientPoolItem   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 80.38%

Importance

Changes 2
Bugs 0 Features 2
Metric Value
wmc 16
c 2
b 0
f 2
lcom 1
cbo 3
dl 0
loc 150
ccs 41
cts 51
cp 0.8038
rs 10

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