【问题标题】:symfony 5 - disable subscribersymfony 5 - 禁用订阅者
【发布时间】:2020-05-28 17:42:36
【问题描述】:

我在 symfony 5 项目中使用 bugsnag 来跟踪异常。我还使用 symfony messenger 和 rabbit 进行繁重的处理。

总体上一切正常,除了在某些情况下,在信使中间件 (RejectRedeliveredMessageMiddleware) 内部,在某些特定情况下会引发异常以触发消息请求,同时避免可能的无限循环 (RejectRedeliveredMessageException)。

异常应该存在,并且行为是正确的。例如,如果进程意外停止(硬重启或终止),则请求消息。逻辑运行良好,自动恢复运行良好。

唯一的问题是 bugsnag 将自己注册为所有内核事件的订阅者,无论是否处理(下面的代码)

$listeners = [
    KernelEvents::REQUEST => ['onKernelRequest', 256],
    KernelEvents::EXCEPTION => ['onKernelException', 128],

];

通常情况下,我们的应用程序会在到达通用事件调度程序之前捕获异常,因此如果不应该报告它们,它们不会被报告。但是,因为它在中间件中,并且一个事件被引发,即使已经被自动重试机制处理,它也会被报告,因此它会产生很多噪音和假阳性。

我需要做的是取消订阅特定事件,但由于我无法触及第 3 方代码(bugsnag 和 messenger),所以我找不到方法。

有没有办法以编程方式从订阅者中删除事件?

【问题讨论】:

    标签: symfony messenger bugsnag


    【解决方案1】:

    注入EventDispatcherInterface 并使用removeSubscriber() 方法。您可以在自定义中间件 https://symfony.com/doc/current/messenger.html#middleware

    中执行此操作

    【讨论】:

    • 这需要确保在引发异常的中间件之前调用我的特定中间件。我正在调查这是否可能。
    【解决方案2】:

    很难说这是否可行,但这是一个角度——当你检测到你的事件被正确处理时,你可以调用$event->stopPropagation(),也许来自你自己的监听器,它应该:“......告诉调度员停止将事件传播给未来的侦听器(即不再通知任何侦听器)"

    https://symfony.com/doc/current/components/event_dispatcher.html#stopping-event-flow-propagation

    【讨论】:

    • 停止传播仅适用于听众,因为没有办法确保订阅者的顺序(至少我没有看到,我可能错过了一些东西但不这么认为)。
    • 只有当他们为订阅者使用priority 标签时才有可能 - 然后您可以使用您自己的具有特定优先级的侦听器,然后决定停止传播。您也许可以查看这段文档,了解如何使用 CompilerPass 或服务装饰覆盖订阅者的服务定义 - 以更适合您的方式:symfony.com/doc/current/bundles/…
    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多