我使用m6web_guzzle
包来注册几个http客户端:
m6web_guzzlehttp:
clients:
myclient:
timeout: 3
headers:
"Accept": "application/json"
delay: 0
verify: false
我想在动态生成的服务上调用方法。在这种情况下,生成的服务名称为:
@m6web_guzzlehttp.guzzle.handlerstack.myclient
以下是我在服务构造函数中的操作:(注入的第三个参数是'@ m6web_guzzlehttp.guzzle.handlerstack.myclient')
/**
* @param array $parameters
* @param Client $client
* @param HandlerStack $handlerStack
*/
public function __construct(array $parameters, Client $client, HandlerStack $handlerStack)
{
$this->parameters = $parameters;
$this->client = $client;
$this->handlerStack->push(Middleware::retry([$this, 'retryDecider']));
}
到目前为止,它运行良好,但如何在push
文件中传输最后一行(services.yml
调用)?或者另一种清理方法来注册这个重试处理程序?
答案 0 :(得分:3)
在您的包的Extension.php
文件中,您可以覆盖加载方法并添加:
$definition = $container->getDefinition('m6web_guzzlehttp.guzzle.handlerstack.myclient');
$definition->addMethodCall('push', [Middleware::retry([$this, 'retryDecider'])]);
答案 1 :(得分:3)
之前提到了编译器传递。这是一种选择。
但您也可以几乎直接在您的服务定义中表达这一点。我说几乎,因为你需要某种代码,因为Symfony服务定义不能(AFAIK)评估为Closure - 这就是我们对Guzzle Middleware所需要的。
我写了这个services.yml作为例子:
m6web_guzzlehttp.guzzle.handlerstack.myclient:
class: GuzzleHttp\HandlerStack
factory: ['GuzzleHttp\HandlerStack', create]
retry_decider:
class: MyBundle\RetryDecider
factory: ['MyBundle\RetryDecider', createInstance]
retry_handler:
class: GuzzleHttp\Middleware
factory: ['GuzzleHttp\Middleware', retry]
arguments:
- '@retry_decider'
handlerstack_pushed:
parent: m6web_guzzlehttp.guzzle.handlerstack.myclient
calls:
- [push, ['@retry_handler']]
m6web_guzzlehttp.guzzle.handlerstack.myclient
- 您的动态服务 - 从已经创建的示例中删除示例。retry_decider
- 你的决策者。我们在createInstance
方法中返回一个Closure。如果需要,可以添加更多参数,只需在YML中添加参数即可。retry_handler
- 这里我们使用我们的决策程序handlerstack_pushed
- 这里我们将push()
我们的处理程序放入堆栈,使用动态服务作为父服务。Etvoilà - 我们拥有动态服务定义的堆栈,但推送了我们的重试中间件。
以下是我们决策者的来源:
<?php
namespace MyBundle;
class RetryDecider {
public static function createInstance() {
return function() {
// do your deciding here
};
}
}
- &GT;您现在拥有服务handlerstack_pushed
,这是完整的堆栈。
请注意,您可以将m6web_guzzlehttp.guzzle.handlerstack.myclient
添加到parameters.yml
:
parameters:
baseHandlerStackService: m6web_guzzlehttp.guzzle.handlerstack.myclient
然后在handlerstack_pushed
上使用它:
handlerstack_pushed:
parent: "%baseHandlerStackService%"
calls:
- [push, ['@retry_handler']]
就像那样更好; - )
答案 2 :(得分:1)
您可以编写一个compiler pass来抓取有问题的定义,并将方法调用添加到其中。