為了設定一些背景關系,我正在開發一個 Symfony 4.4 API,它使用一個名為的供應商將EkinoNewRelicBundle資料傳送到 New Relic API。該供應商使用名為RequestListener訂閱kernel.requestSymonfy 事件的訂閱者來定義要發送到 New Relic API 的資料。
我在特定情況下遇到問題,當身份驗證問題導致 498 時,另一個訂閱者SecurityBundle拋出例外,停止請求處理。不幸的是,EkinoNewRelicBundle 訂閱者的setTransactionName一個名為的方法的優先級低于 SecurityBundle 訂閱者,導致 Ekino 在行程停止時沒有正確設定資料。
通過手工編輯的供應商,我發現一個優先事項10上setTransactionName就足以前被執行SecurityBundle。
我正在尋找一種RequestListener在運行時編輯優先級的優先級的方法。到目前為止,我已經嘗試:
- 覆寫配置,但由于優先級是在類的公共靜態方法中定義的,并且似乎直接加載到 EventDispatcher 中,因此沒有要覆寫的配置;
- 使用編譯器傳遞來操作定義,但與上面相同,沒有要編輯的定義,因為它似乎直接加載到 EventDispatcher 中;
- 擴展Ekino 訂閱者以編輯優先級,從 Ekino 的配置中禁用偵聽器,但這會導致我新定義的訂閱者的配置問題,因為它無法自動裝配。
沒有一種簡單的方法可以更改供應商訂閱者中訂閱事件的優先級嗎?
維護人員在七年前確實談到過這個問題,當時在這個 EkinoNewRelicBundle 問題中仍然可以通過編譯器傳遞來訪問配置。
uj5u.com熱心網友回復:
您可以執行以下操作
- 從 Ekino 的配置中禁用供應商訂閱者
- 創建您自己的高優先級訂閱者/聽眾(您說 10 對您來說就足夠了)
- 將供應商訂閱者注入您的訂閱者/聽眾
- 在您的訂閱者/偵聽器事件方法上,呼叫供應商訂閱者方法并將事件傳遞給它
uj5u.com熱心網友回復:
根據如何覆寫捆綁包的任何部分Symfony 檔案。
如果要修改捆綁包創建的服務,可以使用 服務裝飾。
由于Ekino\NewRelicBundle\Listener\RequestListener是在配置中注冊并由 Symfony 自動配置的服務,因此您可以創建裝飾器并添加自定義getSubscribedEvents()方法來覆寫優先級。
創建裝飾器
// /src/Decorator/EkinoRequestListenerDecorator.php
namespace App\Decorator;
use Ekino\NewRelicBundle\Listener\KernelRequestEvent;
use Ekino\NewRelicBundle\Listener\RequestListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class EkinoRequestListenerDecorator implements EventSubscriberInterface
{
/**
* @var RequestListener
*/
private $decorated;
public function __construct(RequestListener $decorated)
{
$this->decorated = $decorated;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => [
['setApplicationName', 255],
['setIgnoreTransaction', 31],
['setTransactionName', 10],
],
];
}
public function setApplicationName(KernelRequestEvent $event): void
{
$this->decorated->setApplicationName($event);
}
public function setIgnoreTransaction(KernelRequestEvent $event): void
{
$this->decorated->setIgnoreTransaction($event);
}
public function setTransactionName(KernelRequestEvent $event): void
{
$this->decorated->setTransactionName($event);
}
}
配置裝飾器
裝飾選項告訴容器
App\Decorator\EkinoRequestListenerDecorator服務替換了Ekino\NewRelicBundle\Listener\RequestListener服務。
此配置替換
Ekino\NewRelicBundle\Listener\RequestListener為新配置,但保留對舊配置的參考為App\Decorator\EkinoRequestListenerDecorator.inner
# /config/services.yaml
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# ...
App\Decorator\EkinoRequestListenerDecorator:
decorates: Ekino\NewRelicBundle\Listener\RequestListener
arguments: ['@App\Decorator\EkinoRequestListenerDecorator.inner']
除錯事件調度器
php bin/console debug:event-dispatcher kernel.request
結果kernel.request事件分發器
前
Registered Listeners for "kernel.request" Event
===============================================
------- ------------------------------------------------------------------------------------------------------- ----------
Order Callable Priority
------- ------------------------------------------------------------------------------------------------------- ----------
#3 Ekino\NewRelicBundle\Listener\RequestListener::setApplicationName() 255
#8 Ekino\NewRelicBundle\Listener\RequestListener::setIgnoreTransaction() 31
#21 Ekino\NewRelicBundle\Listener\RequestListener::setTransactionName() -10
------- ------------------------------------------------------------------------------------------------------- ----------
后
Registered Listeners for "kernel.request" Event
===============================================
------- ------------------------------------------------------------------------------------------------------- ----------
Order Callable Priority
------- ------------------------------------------------------------------------------------------------------- ----------
#3 App\Decorator\EkinoRequestListenerDecorator::setApplicationName() 255
#8 App\Decorator\EkinoRequestListenerDecorator::setIgnoreTransaction() 31
#13 App\Decorator\EkinoRequestListenerDecorator::setTransactionName() 10
------- ------------------------------------------------------------------------------------------------------- ----------
結果容器事件偵聽器
$instance->addListener('kernel.request', [0 => function () {
return ($this->privates['App\\Decorator\\EkinoRequestListenerDecorator'] ?? $this->getEkinoRequestListenerDecoratorService());
}, 1 => 'setApplicationName'], 255);
$instance->addListener('kernel.request', [0 => function () {
return ($this->privates['App\\Decorator\\EkinoRequestListenerDecorator'] ?? $this->getEkinoRequestListenerDecoratorService());
}, 1 => 'setIgnoreTransaction'], 31);
$instance->addListener('kernel.request', [0 => function () {
return ($this->privates['App\\Decorator\\EkinoRequestListenerDecorator'] ?? $this->getEkinoRequestListenerDecoratorService());
}, 1 => 'setTransactionName'], 10);
//...
protected function getEkinoRequestListenerDecoratorService()
{
return $this->privates['App\\Decorator\\EkinoRequestListenerDecorator'] = new \App\Decorator\EkinoRequestListenerDecorator(new \Ekino\NewRelicBundle\Listener\RequestListener(($this->privates['Ekino\\NewRelicBundle\\NewRelic\\Config'] ?? $this->getConfigService()), ($this->privates['Ekino\\NewRelicBundle\\NewRelic\\BlackholeInteractor'] ?? ($this->privates['Ekino\\NewRelicBundle\\NewRelic\\BlackholeInteractor'] = new \Ekino\NewRelicBundle\NewRelic\BlackholeInteractor())), [], [], new \Ekino\NewRelicBundle\TransactionNamingStrategy\RouteNamingStrategy()));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/335656.html
下一篇:為什么列舉中不允許??計算值?
