How to run bin/console messenger:consume command out of Symfony project?

杀马特。学长 韩版系。学妹 提交于 2021-01-29 07:13:44

问题


I use Messenger Component in a non-Symfony project and Doctrine as a DSN transport. Now I want to test my code and consume the messages on my local machine, but I don't know how to run the messenger command in the console.

I tried to use Symfony\Component\Console\Application and register the \Symfony\Component\Messenger\Command\ConsumeMessagesCommand command in the console but there are many nested dependencies.

Do you have any idea?


回答1:


We actually do this in many projects, even WordPress CLI tools, and we use this library to do it along with this for the transport. It doesn't require Symfony and can work with most queue systems that follow the general standard.

The general idea is that you want something (probably a singleton) to return an instance of Interop\Queue\Context, and here's what we use:

    function createContext(): \Interop\Queue\Context
    {
        $factory = new \Enqueue\Dbal\DbalConnectionFactory(
            sprintf(
                'mysql://%1$s:%2$s@%3$s/%4$s',
                DB_USER,
                DB_PASSWORD,
                DB_HOST,
                DB_NAME
            )
        );

        $context = $factory->createContext();
        $context->createDataBaseTable();
        return $context;
    }

You'll also want something to handle each message, and you'll want to pass the message and consumer to it:

    function handleMessage($message, $consumer)
    {
        // Business logic here
        if($business_logic_failed) {
            $context = createContext();
            $failed_queue = $context->createQueue('FAILED_QUEUE_HERE');
            $context->createProducer()->send($failed_queue, $message);
        } else {
            $consumer->acknowledge($message);
        }
        
    }

Then to use it:

$context = createContext();
$queue = $context->createQueue('QUEUE_NAME_HERE');
$consumer = $context->createConsumer($queue);

// This can be an infinite loop, or a loop for 10 messages and exit, whatever your logic
while(true) {
    // This command will block unless you pass a timeout, so no sleep is needed
    $message = $consumer->receive(/* optional timeout here */);
    handleMessage($message, $consumer);

    // Do whatever you want with message
}

Sprinkle a lot of try/catch around that, too, and make sure that no matter what you acknowledge or fail the message in some way.



来源:https://stackoverflow.com/questions/65005804/how-to-run-bin-console-messengerconsume-command-out-of-symfony-project

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!