【问题标题】:Symfony MessageHandler count how many times a message has been dispatchedSymfony MessageHandler 计算消息被发送的次数
【发布时间】:2020-07-19 12:15:23
【问题描述】:

我正在使用 Symfony Messenger,我想在处理程序中继续发送消息,直到它被发送多次。

我怎样才能跟踪它?

到目前为止,这是我的处理程序类的代码:

class RetryTestHandler implements MessageHandlerInterface
{
    /**
    * @var EntityManagerInterface
    */
    private $entityManager;
    /**
     * @var MessageBusInterface
     */
    private $bus;

    public function __construct(MessageBusInterface $bus, EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
        $this->bus = $bus;
    }

    public function __invoke(RetryTest $message)
    {
        // TODO: Keep dispatching message until it has been dispatched 10 times?
        $this->bus->dispatch(new RetryTest("This is a test!"), [
            new DelayStamp(5000)
        ]);
    }
}

【问题讨论】:

    标签: php symfony symfony4 symfony-messenger


    【解决方案1】:

    要将元数据添加到您的消息中,you can use stamps

    您以后可以在自己的自定义中间件中使用它。

    例如对于这个自定义的StampInterface 实现类:

    class LoopCount implements StampInterface {
    
    
        private int $count; 
    
        public function __construct($count) {
            $this->count = $count;
        }
    
        public function getCount(): int {
            return $this->count;
        } 
    }
    

    然后create your own middleware检查这个邮票并在处理后重新发送:

    class ResendingMiddleware implements MiddlewareInterface
    {
         private $bus;
    
         public function __construct(MessageBusInterface $bus) {
               $this->bus = $bus;
        }
    
        public function handle(Envelope $envelope, StackInterface $stack): Envelope
        {
    
            $envelope = $stack->next()->handle($envelope, $stack);
    
            if (null !== $stamp = $envelope->last(LoopCount::class)) {
                $count = $stamp->getCount();
            } else {
                return $envelope;
            }
    
            // Stop dispatching
            if ($count > 9) {
                return $envelope;
            }
    
            $this->bus->dispatch(new RetryTest("Dit is een test"), [
                new DelayStamp(5000),
                new LoopCount($count + 1)
            ]);
    
            return $envelope;
        }
    

    如果处理超过 9 次,则不做任何事情消费该消息。

    您还需要将中间件添加到配置中:

    framework:
        messenger:
            buses:
                messenger.bus.default:
                    middleware:
                        # service ids that implement Symfony\Component\Messenger\Middleware\MiddlewareInterface
                        - 'App\Middleware\ResendingMiddleware'
    

    我写的很匆忙,目前无法测试,但是基础应该可以帮助您朝着正确的方向前进。测试和调试,你会得到它的工作。稍后我会回来尝试看看是否缺少任何东西

    【讨论】:

    • 感谢您的帮助,但我收到 HandlerException -> 调用未定义的方法 last()。我假设我需要使用信封,因为 last() 方法属于信封?
    • 但是你知道是什么导致了这个错误吗?是不是因为我没有消息作为__invoke方法的参数?
    • 好的,为此编写了一个快速中间件。没有经过全面测试,抱歉;工作中的麻烦,我需要回到那个问题上。但是您应该能够使用以上内容来完成项目。如果您发现错误,请不要犹豫提出修改建议。
    • 那么在中间件handle()方法中我只需要在count超过9的时候返回信封吗?但是返回类型是信封所以我得到一个错误:handle() 的返回值必须是信封的一个实例,没有返回,因为我只在 if 语句中返回信封(超过 9 次检查)。跨度>
    • 我忘了在最后加上return语句。正如我所说,我写的很匆忙,没有测试它。但是在这和文档之间,您应该能够完成实施。也许今天下午我就能正常运行并测试它。
    猜你喜欢
    • 2019-11-28
    • 2022-01-23
    • 2019-04-14
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多