Completed
Pull Request — master (#25)
by Joel
07:56
created

HttpClientPoolItem   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 77.5%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 12
c 1
b 0
f 1
lcom 1
cbo 3
dl 0
loc 114
ccs 31
cts 40
cp 0.775
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A sendRequest() 0 19 3
A sendAsyncRequest() 0 19 2
A getSendingRequestCount() 0 4 1
A disable() 0 5 1
A isDisabled() 0 13 4
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 bool Status of the http client */
24
    private $disabled = false;
25
26
    /** @var \DateTime Time when this client has been disabled */
27
    private $disabledAt;
28
29
    /** @var int|null Number of seconds after this client is reenable, by default null: never reenable this client */
30
    private $reenableAfter;
31
32
    /** @var FlexibleHttpClient A http client responding to async and sync request */
33
    private $client;
34
35
    /**
36
     * {@inheritdoc}
37
     *
38
     * @param null|int $reenableAfter Number of seconds after this client is reenable
39
     */
40 8
    public function __construct($client, $reenableAfter = null)
41
    {
42 8
        $this->client = new FlexibleHttpClient($client);
43 8
        $this->reenableAfter = $reenableAfter;
44 8
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 6
    public function sendRequest(RequestInterface $request)
50
    {
51 6
        if ($this->isDisabled()) {
52
            throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
53
        }
54
55
        try {
56 6
            ++$this->sendingRequestCount;
57 6
            $response = $this->client->sendRequest($request);
58 2
            --$this->sendingRequestCount;
59 6
        } catch (Exception $e) {
60 4
            $this->disable();
61 4
            --$this->sendingRequestCount;
62
63 4
            throw $e;
64
        }
65
66 2
        return $response;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 2
    public function sendAsyncRequest(RequestInterface $request)
73
    {
74 2
        if ($this->isDisabled()) {
75
            throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
76
        }
77
78 2
        ++$this->sendingRequestCount;
79
80
        return $this->client->sendAsyncRequest($request)->then(function ($response) {
81
            --$this->sendingRequestCount;
82
83
            return $response;
84 2
        }, function ($exception) {
85
            $this->disable();
86
            --$this->sendingRequestCount;
87
88
            throw $exception;
89 2
        });
90
    }
91
92
    /**
93
     * Get current number of request that is send by the underlying http client.
94
     *
95
     * @return int
96
     */
97
    public function getSendingRequestCount()
98
    {
99
        return $this->sendingRequestCount;
100
    }
101
102
    /**
103
     * Disable the current client.
104
     */
105 4
    protected function disable()
106
    {
107 4
        $this->disabled = true;
108 4
        $this->disabledAt = new \DateTime('now');
109 4
    }
110
111
    /**
112
     * Whether this client is disabled or not.
113
     *
114
     * Will also reactivate this client if possible
115
     *
116
     * @return bool
117
     */
118 8
    public function isDisabled()
119
    {
120 8
        if ($this->disabled && null !== $this->reenableAfter) {
121
            // Reenable after a certain time
122 2
            $now = new \DateTime();
123
124 2
            if (($now->getTimestamp() - $this->disabledAt->getTimestamp()) >= $this->reenableAfter) {
125 2
                $this->disabled = false;
126 2
            }
127 2
        }
128
129 8
        return $this->disabled;
130
    }
131
}
132