Completed
Pull Request — master (#25)
by Joel
06:53
created

HttpClientPoolItem::sendRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 19
rs 9.4285
cc 3
eloc 12
nc 3
nop 1
1
<?php
2
3
namespace Http\Client\Common;
4
5
use Psr\Http\Message\RequestInterface;
6
use Http\Client\Exception;
7
8
/**
9
 * A HttpClientPoolItem represent a HttpClient inside a Pool.
10
 *
11
 * It is disabled when a request failed and can be reenable after a certain number of seconds
12
 * It also keep tracks of the current number of request the client is currently sending (only usable for async method)
13
 *
14
 * @author Joel Wurtz <[email protected]>
15
 */
16
class HttpClientPoolItem extends FlexibleHttpClient
17
{
18
    /** @var int Number of request this client is actually sending */
19
    private $sendingRequestCount = 0;
20
21
    /** @var bool Status of the http client */
22
    private $disabled = false;
23
24
    /** @var \DateTime Time when this client has been disabled */
25
    private $disabledAt;
26
27
    /** @var int|null Number of seconds after this client is reenable, by default null: never reenable this client */
28
    private $reenableAfter;
29
30
    /**
31
     * {@inheritdoc}
32
     *
33
     * @param null|int $reenableAfter Number of seconds after this client is reenable
34
     */
35
    public function __construct($client, $reenableAfter = null)
36
    {
37
        parent::__construct($client);
38
39
        $this->reenableAfter = $reenableAfter;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function sendRequest(RequestInterface $request)
46
    {
47
        if ($this->isDisabled()) {
48
            throw new Exception\RequestException('Cannot send request as this client as been disabled', $request);
49
        }
50
51
        try {
52
            ++$this->sendingRequestCount;
53
            $response = parent::sendRequest($request);
54
            --$this->sendingRequestCount;
55
        } catch (Exception $e) {
56
            $this->disable();
57
            --$this->sendingRequestCount;
58
59
            throw $e;
60
        }
61
62
        return $response;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function sendAsyncRequest(RequestInterface $request)
69
    {
70
        if ($this->isDisabled()) {
71
            throw new Exception\RequestException('Cannot send request as this client as been disabled', $request);
72
        }
73
74
        ++$this->sendingRequestCount;
75
76
        return parent::sendAsyncRequest($request)->then(function ($response) {
77
            --$this->sendingRequestCount;
78
79
            return $response;
80
        }, function ($exception) {
81
            $this->disable();
82
            --$this->sendingRequestCount;
83
84
            throw $exception;
85
        });
86
    }
87
88
    /**
89
     * Get current number of request that is send by the underlying http client.
90
     *
91
     * @return int
92
     */
93
    public function getSendingRequestCount()
94
    {
95
        return $this->sendingRequestCount;
96
    }
97
98
    /**
99
     * Disable the current client.
100
     */
101
    protected function disable()
102
    {
103
        $this->disabled = true;
104
        $this->disabledAt = new \DateTime('now');
105
    }
106
107
    /**
108
     * Whether this client is disabled or not.
109
     *
110
     * Will also reactivate this client if possible
111
     *
112
     * @return bool
113
     */
114
    public function isDisabled()
115
    {
116
        if ($this->disabled && null !== $this->reenableAfter) {
117
            // Reenable after a certain time
118
            $now = new \DateTime();
119
120
            if (($now->getTimestamp() - $this->disabledAt->getTimestamp()) >= $this->reenableAfter) {
121
                $this->disabled = false;
122
            }
123
        }
124
125
        return $this->disabled;
126
    }
127
}
128