Messenger

Enfin stable

Robin Chalas

  • @Les-Tilleuls.coop
  • @Symfony Core Team

 

GitHub @chalasr

Twitter @chalas_r

 Introduit en Symfony 4.1

Experimental ?

  • S'applique sur une feature ou un composant
  • Non couvert par la promesse de rétrocompatibilité
  • Pour une version mineure maximum

Message

<?php

// src/Entity/Greeting.php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ApiResource(
 *     output=false,
 *     messenger=true,
 *     collectionOperations={"get", "post"={"status"=202}},
 *     itemOperations={}
 * )
 */
class Greeting
{
    /**
     * @Assert\NotBlank
     */
    public ?string $name = '';
}

Message Handler

<?php

// src/Handler/GreetingHandler.php

namespace App\Handler;

use App\Entity\Greeting;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

final class GreetingHandler implements MessageHandlerInterface
{
    public function __invoke(Greeting $greeting)
    {
        // business logic
    }
}

Config

# config/packages/messenger.yaml

framework:
    messenger:
        transports:
            redis: '%env(MESSENGER_TRANSPORT_DSN)%'

        routing:
            'App\Entity\Greeting': redis
###> .env ###

###> symfony/messenger ###
MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
###< symfony/messenger ###

Middleware (4.1)

<?php

// src/Middleware/MyOwnMiddleware.php

namespace App\Middleware;

use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\EnvelopeAwareInterface;

class MyOwnMiddleware implements MiddlewareInterface, EnvelopeAwareInterface
{
    public function handle($envelope, callable $next)
    {
        if (null !== $envelope->get(ReceivedMessage::class)) {
            // Message just has been received
            // Add another envelope item
            $envelope = $envelope->with(new AnotherEnvelopeItem(/* ... */));
        }

        return $next($envelope);
    }
}

Middleware (4.2+)

<?php

// src/Middleware/MyOwnMiddleware.php

namespace App\Middleware;

use App\Message\Stamp\AnotherStamp;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;

class MyOwnMiddleware implements MiddlewareInterface
{
    public function handle(Envelope $envelope, StackInterface $stack): Envelope
    {
        if (null !== $envelope->last(ReceivedStamp::class)) {
            // Message just has been received
            // Add another stamp
            $envelope = $envelope->with(new AnotherStamp(/* ... */));
        }

        return $stack->next()->handle($envelope, $stack);
    }
}

Echecs d'envoi & retry (4.3+)

# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            redis:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'

                # default configuration
                retry_strategy:
                    max_retries: 3
                    # milliseconds delay
                    delay: 1000
                    # causes the delay to be higher before each retry
                    # e.g. 1 second delay, 2 seconds, 4 seconds
                    multiplier: 2
                    max_delay: 0

Failure transport

# config/packages/messenger.yaml

framework:
    messenger:
        failure_transport: failed

        transports:
            redis: '%env(MESSENGER_TRANSPORT_DSN)%'
            failed: 'doctrine://default?queue_name=failed'

        routing:
            'App\Entity\Greeting': redis

Retry manuel

# see all messages in the failure transport
$ php bin/console messenger:failed:show

# see details about a specific failure
$ php bin/console messenger:failed:show 20 -vv

# retry all messages one-by-one
$ php bin/console messenger:failed:retry -vv

# retry specific messages
$ php bin/console messenger:failed:retry 20 30 --force

# php bin/console messenger:failed:remove 20
$ php bin/console messenger:failed:remove 20

# remove messages without retrying them and show each message before removing it
$ php bin/console messenger:failed:remove 20 30 --show-messages

Transports

Merci !