@@ -4,121 +4,121 @@ |
||
4 | 4 | |
5 | 5 | class Guzzler |
6 | 6 | { |
7 | - private $curl; |
|
8 | - private $handler; |
|
9 | - private $client; |
|
10 | - private $concurrent = 0; |
|
11 | - private $maxConcurrent; |
|
12 | - private $usleep; |
|
13 | - private $lastHeaders = []; |
|
14 | - private $etagTTL = 86400; |
|
15 | - |
|
16 | - public function __construct($maxConcurrent = 10, $usleep = 100000, $userAgent = 'cvweiss/guzzler/', $curlOptions = []) |
|
17 | - { |
|
18 | - $curlOptions = $curlOptions == [] ? [CURLOPT_FRESH_CONNECT => false] : $curlOptions; |
|
19 | - |
|
20 | - $this->curl = new \GuzzleHttp\Handler\CurlMultiHandler(); |
|
21 | - $this->handler = \GuzzleHttp\HandlerStack::create($this->curl); |
|
22 | - $this->client = new \GuzzleHttp\Client(['curl' => $curlOptions, 'connect_timeout' => 10, 'timeout' => 10, 'handler' => $this->handler, 'User-Agent' => $userAgent]); |
|
23 | - $this->maxConcurrent = max($maxConcurrent, 1); |
|
24 | - $this->usleep = max(0, min(1000000, (int) $usleep)); |
|
25 | - } |
|
26 | - |
|
27 | - public function tick() |
|
28 | - { |
|
29 | - $ms = microtime(); |
|
30 | - do { |
|
31 | - $this->curl->tick(); |
|
32 | - if ($this->concurrent >= $this->maxConcurrent) usleep(max(1, min(1000000, $this->usleep))); |
|
33 | - } while ($this->concurrent >= $this->maxConcurrent); |
|
34 | - return max(0, microtime() - $ms); |
|
35 | - } |
|
36 | - |
|
37 | - public function finish() |
|
38 | - { |
|
39 | - $ms = microtime(); |
|
40 | - $this->curl->execute(); |
|
41 | - return max(0, microtime() - $ms); |
|
42 | - } |
|
43 | - |
|
44 | - public function inc() |
|
45 | - { |
|
46 | - $this->concurrent++; |
|
47 | - } |
|
48 | - |
|
49 | - public function dec() |
|
50 | - { |
|
51 | - $this->concurrent--; |
|
52 | - } |
|
53 | - |
|
54 | - public function call($uri, $fulfilled, $rejected, $params = [], $setup = [], $callType = 'GET', $body = null) |
|
55 | - { |
|
56 | - $this->verifyCallable($fulfilled); |
|
57 | - $this->verifyCallable($rejected); |
|
58 | - |
|
59 | - while ($this->concurrent >= $this->maxConcurrent) $this->tick(); |
|
60 | - |
|
61 | - $params['uri'] = $uri; |
|
62 | - $params['fulfilled'] = $fulfilled; |
|
63 | - $params['rejected'] = $rejected; |
|
64 | - $params['setup'] = $setup; |
|
65 | - $params['callType'] = $callType; |
|
66 | - $params['body'] = $body; |
|
67 | - |
|
68 | - $redis = $this->applyEtag($setup, $params); |
|
69 | - |
|
70 | - $guzzler = $this; |
|
71 | - $request = new \GuzzleHttp\Psr7\Request($callType, $uri, $setup, $body); |
|
72 | - $this->client->sendAsync($request)->then( |
|
73 | - function($response) use (&$guzzler, $fulfilled, &$params, $redis) { |
|
74 | - $guzzler->dec(); |
|
75 | - $content = (string) $response->getBody(); |
|
76 | - $this->lastHeaders = array_change_key_case($response->getHeaders()); |
|
77 | - $this->applyEtagPost($this->lastHeaders, $params['uri'], $redis); |
|
78 | - $fulfilled($guzzler, $params, $content); |
|
79 | - }, |
|
80 | - function($connectionException) use (&$guzzler, &$rejected, &$params) { |
|
81 | - $guzzler->dec(); |
|
82 | - $response = $connectionException->getResponse(); |
|
83 | - $this->lastHeaders = $response == null ? [] : array_change_key_case($response->getHeaders()); |
|
84 | - $params['content'] = method_exists($response, "getBody") ? (string) $response->getBody() : ""; |
|
85 | - $rejected($guzzler, $params, $connectionException); |
|
86 | - }); |
|
87 | - $this->inc(); |
|
88 | - } |
|
89 | - |
|
90 | - protected function applyEtag(&$setup, $params) |
|
91 | - { |
|
92 | - $redis = isset($setup['etag']) ? $setup['etag'] : null; |
|
93 | - if ($redis !== null && $params['callType'] == 'GET') { |
|
94 | - $etag = $redis->get("guzzler:etags:" . $params['uri']); |
|
95 | - if ($etag != "") $setup['If-None-Match'] = $etag; |
|
96 | - } |
|
97 | - unset($setup['etag']); |
|
98 | - return $redis; |
|
99 | - } |
|
100 | - |
|
101 | - protected function applyEtagPost($headers, $uri, $redis) |
|
102 | - { |
|
103 | - if (isset($headers['etag']) && $redis !== null) { |
|
104 | - $redis->setex("guzzler:etags:$uri", $this->etagTTL, $headers['etag'][0]); |
|
105 | - } |
|
106 | - } |
|
107 | - |
|
108 | - public function verifyCallable($callable) |
|
109 | - { |
|
110 | - if (!is_callable($callable)) { |
|
111 | - throw new \InvalidArgumentException(print_r($callable, true) . " is not a callable function"); |
|
112 | - } |
|
113 | - } |
|
114 | - |
|
115 | - public function getLastHeaders() |
|
116 | - { |
|
117 | - return $this->lastHeaders; |
|
118 | - } |
|
119 | - |
|
120 | - public function setEtagTTL($ttl) |
|
121 | - { |
|
122 | - $this->etagTTL = $ttl; |
|
123 | - } |
|
7 | + private $curl; |
|
8 | + private $handler; |
|
9 | + private $client; |
|
10 | + private $concurrent = 0; |
|
11 | + private $maxConcurrent; |
|
12 | + private $usleep; |
|
13 | + private $lastHeaders = []; |
|
14 | + private $etagTTL = 86400; |
|
15 | + |
|
16 | + public function __construct($maxConcurrent = 10, $usleep = 100000, $userAgent = 'cvweiss/guzzler/', $curlOptions = []) |
|
17 | + { |
|
18 | + $curlOptions = $curlOptions == [] ? [CURLOPT_FRESH_CONNECT => false] : $curlOptions; |
|
19 | + |
|
20 | + $this->curl = new \GuzzleHttp\Handler\CurlMultiHandler(); |
|
21 | + $this->handler = \GuzzleHttp\HandlerStack::create($this->curl); |
|
22 | + $this->client = new \GuzzleHttp\Client(['curl' => $curlOptions, 'connect_timeout' => 10, 'timeout' => 10, 'handler' => $this->handler, 'User-Agent' => $userAgent]); |
|
23 | + $this->maxConcurrent = max($maxConcurrent, 1); |
|
24 | + $this->usleep = max(0, min(1000000, (int) $usleep)); |
|
25 | + } |
|
26 | + |
|
27 | + public function tick() |
|
28 | + { |
|
29 | + $ms = microtime(); |
|
30 | + do { |
|
31 | + $this->curl->tick(); |
|
32 | + if ($this->concurrent >= $this->maxConcurrent) usleep(max(1, min(1000000, $this->usleep))); |
|
33 | + } while ($this->concurrent >= $this->maxConcurrent); |
|
34 | + return max(0, microtime() - $ms); |
|
35 | + } |
|
36 | + |
|
37 | + public function finish() |
|
38 | + { |
|
39 | + $ms = microtime(); |
|
40 | + $this->curl->execute(); |
|
41 | + return max(0, microtime() - $ms); |
|
42 | + } |
|
43 | + |
|
44 | + public function inc() |
|
45 | + { |
|
46 | + $this->concurrent++; |
|
47 | + } |
|
48 | + |
|
49 | + public function dec() |
|
50 | + { |
|
51 | + $this->concurrent--; |
|
52 | + } |
|
53 | + |
|
54 | + public function call($uri, $fulfilled, $rejected, $params = [], $setup = [], $callType = 'GET', $body = null) |
|
55 | + { |
|
56 | + $this->verifyCallable($fulfilled); |
|
57 | + $this->verifyCallable($rejected); |
|
58 | + |
|
59 | + while ($this->concurrent >= $this->maxConcurrent) $this->tick(); |
|
60 | + |
|
61 | + $params['uri'] = $uri; |
|
62 | + $params['fulfilled'] = $fulfilled; |
|
63 | + $params['rejected'] = $rejected; |
|
64 | + $params['setup'] = $setup; |
|
65 | + $params['callType'] = $callType; |
|
66 | + $params['body'] = $body; |
|
67 | + |
|
68 | + $redis = $this->applyEtag($setup, $params); |
|
69 | + |
|
70 | + $guzzler = $this; |
|
71 | + $request = new \GuzzleHttp\Psr7\Request($callType, $uri, $setup, $body); |
|
72 | + $this->client->sendAsync($request)->then( |
|
73 | + function($response) use (&$guzzler, $fulfilled, &$params, $redis) { |
|
74 | + $guzzler->dec(); |
|
75 | + $content = (string) $response->getBody(); |
|
76 | + $this->lastHeaders = array_change_key_case($response->getHeaders()); |
|
77 | + $this->applyEtagPost($this->lastHeaders, $params['uri'], $redis); |
|
78 | + $fulfilled($guzzler, $params, $content); |
|
79 | + }, |
|
80 | + function($connectionException) use (&$guzzler, &$rejected, &$params) { |
|
81 | + $guzzler->dec(); |
|
82 | + $response = $connectionException->getResponse(); |
|
83 | + $this->lastHeaders = $response == null ? [] : array_change_key_case($response->getHeaders()); |
|
84 | + $params['content'] = method_exists($response, "getBody") ? (string) $response->getBody() : ""; |
|
85 | + $rejected($guzzler, $params, $connectionException); |
|
86 | + }); |
|
87 | + $this->inc(); |
|
88 | + } |
|
89 | + |
|
90 | + protected function applyEtag(&$setup, $params) |
|
91 | + { |
|
92 | + $redis = isset($setup['etag']) ? $setup['etag'] : null; |
|
93 | + if ($redis !== null && $params['callType'] == 'GET') { |
|
94 | + $etag = $redis->get("guzzler:etags:" . $params['uri']); |
|
95 | + if ($etag != "") $setup['If-None-Match'] = $etag; |
|
96 | + } |
|
97 | + unset($setup['etag']); |
|
98 | + return $redis; |
|
99 | + } |
|
100 | + |
|
101 | + protected function applyEtagPost($headers, $uri, $redis) |
|
102 | + { |
|
103 | + if (isset($headers['etag']) && $redis !== null) { |
|
104 | + $redis->setex("guzzler:etags:$uri", $this->etagTTL, $headers['etag'][0]); |
|
105 | + } |
|
106 | + } |
|
107 | + |
|
108 | + public function verifyCallable($callable) |
|
109 | + { |
|
110 | + if (!is_callable($callable)) { |
|
111 | + throw new \InvalidArgumentException(print_r($callable, true) . " is not a callable function"); |
|
112 | + } |
|
113 | + } |
|
114 | + |
|
115 | + public function getLastHeaders() |
|
116 | + { |
|
117 | + return $this->lastHeaders; |
|
118 | + } |
|
119 | + |
|
120 | + public function setEtagTTL($ttl) |
|
121 | + { |
|
122 | + $this->etagTTL = $ttl; |
|
123 | + } |
|
124 | 124 | } |
@@ -29,7 +29,9 @@ discard block |
||
29 | 29 | $ms = microtime(); |
30 | 30 | do { |
31 | 31 | $this->curl->tick(); |
32 | - if ($this->concurrent >= $this->maxConcurrent) usleep(max(1, min(1000000, $this->usleep))); |
|
32 | + if ($this->concurrent >= $this->maxConcurrent) { |
|
33 | + usleep(max(1, min(1000000, $this->usleep))); |
|
34 | + } |
|
33 | 35 | } while ($this->concurrent >= $this->maxConcurrent); |
34 | 36 | return max(0, microtime() - $ms); |
35 | 37 | } |
@@ -56,7 +58,9 @@ discard block |
||
56 | 58 | $this->verifyCallable($fulfilled); |
57 | 59 | $this->verifyCallable($rejected); |
58 | 60 | |
59 | - while ($this->concurrent >= $this->maxConcurrent) $this->tick(); |
|
61 | + while ($this->concurrent >= $this->maxConcurrent) { |
|
62 | + $this->tick(); |
|
63 | + } |
|
60 | 64 | |
61 | 65 | $params['uri'] = $uri; |
62 | 66 | $params['fulfilled'] = $fulfilled; |
@@ -92,7 +96,9 @@ discard block |
||
92 | 96 | $redis = isset($setup['etag']) ? $setup['etag'] : null; |
93 | 97 | if ($redis !== null && $params['callType'] == 'GET') { |
94 | 98 | $etag = $redis->get("guzzler:etags:" . $params['uri']); |
95 | - if ($etag != "") $setup['If-None-Match'] = $etag; |
|
99 | + if ($etag != "") { |
|
100 | + $setup['If-None-Match'] = $etag; |
|
101 | + } |
|
96 | 102 | } |
97 | 103 | unset($setup['etag']); |
98 | 104 | return $redis; |