Skip to content

Commit 1cd6454

Browse files
committed
make guzzle service configuration more complex so we can use retry middleware.
1 parent b974e46 commit 1cd6454

File tree

4 files changed

+43
-26
lines changed

4 files changed

+43
-26
lines changed

Guzzle/RetryMiddleware.php

+9-11
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22

33
namespace RShief\Nab3aBundle\Guzzle;
44

5-
use GuzzleHttp\Exception;
5+
use GuzzleHttp\Exception\ConnectException;
66
use GuzzleHttp\Middleware;
77
use GuzzleHttp\Psr7;
88
use Psr\Http\Message\RequestInterface;
9-
use Psr\Log\LoggerAwareTrait;
9+
use Symfony\Component\VarDumper\VarDumper;
1010

1111
class RetryMiddleware
1212
{
13-
use LoggerAwareTrait;
14-
1513
/**
1614
* @var callable
1715
*/
@@ -43,30 +41,30 @@ public static function retry()
4341
private static function retryMiddlewares()
4442
{
4543
return array(
44+
[Middleware::retry(self::connectExceptionDecider(), self::linearDelay(250, 16000)), 'connect_error'],
4645
[Middleware::retry(self::httpErrorDecider(), self::exponentialDelay(5000, 320000)), 'http_error'],
4746
[Middleware::retry(self::rateLimitErrorDecider(), self::exponentialDelay(60000)), 'rate_limit'],
48-
[Middleware::retry(self::connectExceptionDecider(), self::linearDelay(250, 16000)), 'connect_error'],
4947
);
5048
}
5149

5250
public static function connectExceptionDecider()
5351
{
54-
return function ($retries, Psr7\Request $request, Psr7\Response $response = null, Exception\RequestException $exception = null) {
55-
return $exception instanceof Exception\ConnectException;
52+
return function ($retries, Psr7\Request $request, Psr7\Response $response = null, $error = null) {
53+
return ! (bool) $response || $error instanceof ConnectException;
5654
};
5755
}
5856

5957
public static function rateLimitErrorDecider()
6058
{
61-
return function ($retries, Psr7\Request $request, Psr7\Response $response = null, Exception\RequestException $exception = null) {
62-
return $exception instanceof Exception\ClientException && $exception->hasResponse() && $exception->getResponse()->getStatusCode() === 420;
59+
return function ($retries, Psr7\Request $request, Psr7\Response $response = null, $error = null) {
60+
return $response && $response->getStatusCode() === 420;
6361
};
6462
}
6563

6664
public static function httpErrorDecider()
6765
{
68-
return function ($retries, Psr7\Request $request, Psr7\Response $response = null, Exception\RequestException $exception = null) {
69-
return $exception instanceof Exception\BadResponseException;
66+
return function ($retries, Psr7\Request $request, Psr7\Response $response = null, $error = null) {
67+
return $response && $response->getStatusCode() >= 400;
7068
};
7169
}
7270

Guzzle/StackMiddlewareCompilerPass.php

+20-5
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,36 @@ public function process(ContainerBuilder $container)
2121
$stacks = [];
2222
foreach ($serviceIds as $serviceId => $tags) {
2323
foreach ($tags as $tag) {
24-
$clientId = $tag['id'];
25-
$stacks[$clientId][] = $serviceId;
24+
$clientId = $tag['client'];
25+
unset($tag['client']);
26+
$stacks[$clientId][] = array_merge(['method' => 'push'], $tag, ['service' => $serviceId]);
2627
}
2728
}
2829

29-
foreach ($stacks as $clientId => $middlewareIds) {
30+
foreach ($stacks as $clientId => $middlewares) {
3031
$clientDefinition = $container->getDefinition($clientId);
3132
$arguments = $clientDefinition->getArguments();
3233

3334
$handlerDefinition = self::hasHandlerDefinition($arguments) ? self::getHandlerDefinition($arguments) : self::newHandlerDefinition($container);
3435

3536
$stackDefinition = new DefinitionDecorator('nab3a.guzzle.handler_stack');
3637
$stackDefinition->setArguments([$handlerDefinition]);
37-
foreach ($middlewareIds as $name => $middlewareId) {
38-
$stackDefinition->addMethodCall('push', [new Reference($middlewareId), $middlewareId]);
38+
$earlyMiddleware = array_filter($middlewares, function ($middleware) {
39+
return !array_key_exists('before', $middleware) && !array_key_exists('after', $middleware);
40+
});
41+
$lateMiddleware = array_diff_key($middlewares, $earlyMiddleware);
42+
foreach ($earlyMiddleware + $lateMiddleware as $middleware) {
43+
$method = $middleware['method'];
44+
$stackArguments = [
45+
new Reference($middleware['service']),
46+
$middleware['middleware_name']
47+
];
48+
if (isset($middleware['before']) || isset($middleware['after'])) {
49+
$method = isset($middleware['before']) ? 'before' : 'after';
50+
array_unshift($stackArguments, $middleware[$method]);
51+
}
52+
53+
$stackDefinition->addMethodCall($method, $stackArguments);
3954
}
4055

4156
$arguments[0]['handler'] = $stackDefinition;

Resources/config/guzzle.yml

+7-9
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@ services:
77
shared: false
88
factory: [ GuzzleHttp\Middleware, httpErrors ]
99
tags:
10-
- { name: guzzle.middleware, id: nab3a.guzzle.client }
11-
- { name: guzzle.middleware, id: nab3a.twitter.guzzle.client }
10+
- { name: guzzle.middleware, client: nab3a.guzzle.client, middleware_name: http_errors }
11+
- { name: guzzle.middleware, client: nab3a.twitter.guzzle.client, middleware_name: http_errors }
1212

1313
nab3a.guzzle.middleware.prepare_body:
1414
class: Closure
1515
public: false
1616
shared: false
1717
factory: [ GuzzleHttp\Middleware, prepareBody ]
1818
tags:
19-
- { name: guzzle.middleware, id: nab3a.guzzle.client }
20-
- { name: guzzle.middleware, id: nab3a.twitter.guzzle.client }
19+
- { name: guzzle.middleware, client: nab3a.guzzle.client, middleware_name: prepare_body }
20+
- { name: guzzle.middleware, client: nab3a.twitter.guzzle.client, middleware_name: prepare_body }
2121

2222
nab3a.guzzle.middleware.history:
2323
class: Closure
2424
factory: [ RShief\Nab3aBundle\Guzzle\HistoryMiddleware, history ]
2525
public: false
2626
shared: false
2727
tags:
28-
- { name: guzzle.middleware, id: nab3a.twitter.guzzle.client }
28+
- { name: guzzle.middleware, client: nab3a.twitter.guzzle.client, middleware_name: history }
2929

3030
nab3a.guzzle.middleware.history.container:
3131
class: ArrayObject
@@ -36,8 +36,6 @@ services:
3636
public: false
3737
shared: false
3838
factory: [ RShief\Nab3aBundle\Guzzle\RetryMiddleware, retry ]
39-
tags:
40-
- { name: guzzle.middleware, id: nab3a.twitter.guzzle.client }
4139

4240
nab3a.guzzle.middleware.oauth:
4341
class: GuzzleHttp\Subscriber\Oauth\Oauth1
@@ -51,8 +49,8 @@ services:
5149
arguments: [ '@?logger', '@nab3a.guzzle.middleware.log.formatter' ]
5250
tags:
5351
- { name: monolog.logger, channel: guzzle }
54-
- { name: guzzle.middleware, id: nab3a.guzzle.client }
55-
- { name: guzzle.middleware, id: nab3a.twitter.guzzle.client }
52+
- { name: guzzle.middleware, client: nab3a.guzzle.client, middleware_name: log, after: retry }
53+
- { name: guzzle.middleware, client: nab3a.twitter.guzzle.client, middleware_name: log, after: retry }
5654
public: false
5755
shared: false
5856

Resources/config/twitter.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,10 @@ services:
5252
token: '%nab3a.twitter.access_token%'
5353
token_secret: '%nab3a.twitter.access_token_secret%'
5454
tags:
55-
- { name: guzzle.middleware, id: nab3a.twitter.guzzle.client }
55+
- { name: guzzle.middleware, client: nab3a.twitter.guzzle.client, middleware_name: oauth }
56+
57+
nab3a.twitter.guzzle.middleware.retry:
58+
parent: nab3a.guzzle.middleware.retry
59+
tags:
60+
- { name: guzzle.middleware, client: nab3a.twitter.guzzle.client, middleware_name: retry }
61+

0 commit comments

Comments
 (0)