Share
Embed
Using the Symfony Messenger
Slides for my workshop at Dutch PHP Conference 2019.
Denis Brumann
June 06, 2019
Transcript
32 slides
-
AGENDA 1. Quick introduction round 2. Setting up the project
skeleton, while I guide you through the example code 3. Presentation: Introduction to messenger-concepts 4. Task 1: Introduce synchronous message processing 5. Presentation: Transports for async processing 6. Task 2: Pick your challenge(s) 7. Questions -
GOALS Have fun Learn about the Messenger component Just 3
hours won't make you an expert, but hopefully you: • have a feeling whether this component is useful to you • maybe you get interested in message-based architecture Feel free to ask questions at any time. If you have suggestions how I can better suit your learning style, please let me know and I will adjust -
WHO AM I Denis Brumann Software Developer at SensioLabs Germany
in Berlin Twitter: @dbrumann Email: [email protected] Personal Focus: • Migrating client's legacy projects Symfony experience: • started with 2.0 • currently using 3.4 in client project • for private projects I try to use latest version possible -
SETTING UP THE PROJECT git remote add dpc2019 \ https://github.com/dbrumann/dpc2019-workshop.git
git fetch dpc2019 git checkout -b develop dpc2019/master \ --no-track -
CORE CONCEPTS Message Data Object containing all relevant data Message
Bus Takes a message and delegates it to the right recipient Message Handler Takes a Message-object and handles it, i.e. processes it -
ADVANCED CONCEPTS Envelope Wrapper for a Message and contextual info
(stamps) Stamp Provides context to/from a Middleware Middleware Controls the behavior of the Message Bus -
MESSAGE BUS interface MessageBusInterface { /** * Dispatches the given
message. * * @param object|Envelope $message The message or the message * pre-wrapped in an envelope * @param StampInterface[] $stamps */ public function dispatch($message, array $stamps = []): Envelope; } -
SENDING A MESSAGE class MyService { private $messageBus; public function
__construct(MessageBusInterface $messageBus) { $this->messageBus = $messageBus; } public function doSomething(string $url) { $this->messageBus->dispatch(new TakeScreenshotMessage($url)); } } -
SENDING A MESSAGE public function index(Request $request): Response { if
($request->isMethod('POST')) { $url = trim($request->request->get('url')); $this->dispatchMessage(new TakeScreenshotMessage($url)); } return $this->render('screenshot.html.twig'); } -
TASK 1 • Install the Messenger component • Modify App\Registration\Registration::register()
or the corresponding Controller-action App\Controller\RegistrationController::register() to use the Messenger instead • Create a Message-object (you can take the Form-object as a reference point) • Dispatch the Message using the MessageBus -
TASK 1 • Install the Messenger component • Modify App\Registration\Registration::register()
or the corresponding Controller-action App\Controller\RegistrationController::register() to use the Messenger instead • Create a Message-object (you can take the Form-object as a reference point) • Dispatch the Message using the MessageBus • Create a MessageHandler -
HANDLING MESSAGES class ScreenshotMessageSubscriber implements MessageSubscriberInterface { public static function
getHandledMessages(): iterable { yield TakeScreenshotMessage::class => [ 'method' => 'takeScreenshot' ]; } public function takeScreenshot(TakeScreenshotMessage $message) { ... } } -
AVAILABLE TRANSPORTS AMQP (RabbitMQ) Redis Doctrine (using a DBAL-Connection) InMemory
(for tests) Need more? Enqueue provides many more adapters -
PICK YOUR CHALLENGE(S) • Validating messages inside the MessageBus •
Sending registration mails with Symfony Mailer (using async transport) • Creating an implicit workflow using many sync/async-handled messages • Adding capability to deal with failing messages • Looking into CQRS • Creating a CommandBus, (QueryBus), EventBus -
framework: messenger: transports: sync: 'sync://' async: '%env(MESSENGER_TRANSPORT_DSN)%' routing: # Route
your messages to the transports App\Message\RequestRegistrationQuery: 'sync' App\Message\RegisterUserCommand: 'async' App\Message\UserRegisteredEvent: 'async' -
# default configuration retry_strategy: max_retries: 3 delay: 1000 # delay
for first retry multiplier: 2 # multiply delay with each try max_delay: 0 # service: null # id for custom RetryStrategy