Chapters
48 Chapters
|
5:05:05
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This tutorial is built with Symfony 4.3, but will work well on Symfony 4.4 or 5.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // v1.8.0
"doctrine/doctrine-bundle": "^1.6.10", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.6.3
"intervention/image": "^2.4", // 2.4.2
"league/flysystem-bundle": "^1.0", // 1.1.0
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.1
"sensio/framework-extra-bundle": "^5.3", // v5.3.1
"symfony/console": "4.3.*", // v4.3.2
"symfony/dotenv": "4.3.*", // v4.3.2
"symfony/flex": "^1.9", // v1.21.6
"symfony/framework-bundle": "4.3.*", // v4.3.2
"symfony/messenger": "4.3.*", // v4.3.4
"symfony/property-access": "4.3.*", // v4.3.2
"symfony/property-info": "4.3.*", // v4.3.2
"symfony/serializer": "4.3.*", // v4.3.2
"symfony/validator": "4.3.*", // v4.3.2
"symfony/webpack-encore-bundle": "^1.5", // v1.6.2
"symfony/yaml": "4.3.*" // v4.3.2
},
"require-dev": {
"easycorp/easy-log-handler": "^1.0.7", // v1.0.7
"symfony/debug-bundle": "4.3.*", // v4.3.2
"symfony/maker-bundle": "^1.0", // v1.12.0
"symfony/monolog-bundle": "^3.0", // v3.4.0
"symfony/stopwatch": "4.3.*", // v4.3.2
"symfony/twig-bundle": "4.3.*", // v4.3.2
"symfony/var-dumper": "4.3.*", // v4.3.2
"symfony/web-profiler-bundle": "4.3.*" // v4.3.2
}
}
12 Comments
I have a lot of messages to send. About 300,000
Process of adding using method "dispatch" take a lot of time.
Is it possible to add messages similar like this?
as we do it in EntityManager
Hey Dmitriy,
IIRC there's no something similar to Doctrine batch processing in Messenger, but probably instead of trying to dispatch like you suggested you better create a different "batch" message? Something like
ProductStockBatchthat will take an array of thoseintval($item[0])andintval($item[2]arguments? something like:Something like this, also you may want to add some limits to that array or modify it that way that when you hit e.g. about 100 entires in that
$productStocksDataarray - dispatch the event.Then in the message handler you would need to deal with an array.
I hope that helps
Cheers!
Thanks for the answer. But I don’t understand how to handle messages in this way.
What if the connection is lost or some element will be processed with an error. Will the entire processing process have to start over again?
The problem is that the messages in this case are stored in an array and not as individual messages.
Hey Dmitriy,
I see. Well, if something will go wrong - the message will hit the failed queue, but to know what data were already process and what were not when you will retry again - that's a tricky thing than. Probably you could check if the specific data were processed? I mean, if you create something - you can double-check if it was already created before try to create it again. And if it was - just skip it. Or if you just update soemthing - probably not a big deal to process the update again if it's safe, if nothing will be changed because changes were already applied - ok then, easy win. Or you probably could "log" the processing somehow, create an extra log table that will hold the IDs of entries that were successfully handled before, and so you can skip processing it again base on that.
Otherwise, yeah, you would need to fire those many individual ProductStock events. Probably there's a way to extend the Messenger class and add some more custom implementation that would help with kind of "transactioning" as you mentioned in your first message, but I'm not sure how to easily achieve it, never thought about it before.
I hope that helps!
Cheers!
Is there any reason why DelayStamp for a message dispatched in the handler doesn't work for me.
When I dispatch Message from the controller DelayStamp works.
Hey Kris,
That's unexpected, the DelayStamp should just work (and actually, it does work for me). How do you start the worker? I'm wondering if you use any special config for it
Also, remember that the delay time it's in milliseconds
Cheers!
Hi Ryan, I have a question. from what i understand the idea of taking the load off the web server would be to make the service asynchronous so that the response is returned as quickly as possible to the client and finish the request faster, with that the (same server) can process the rest of the work as delete
the photo file without this process being linked to a web request, am I right? I believed that we would have to separate our code on different servers to perform each step as if they were microservices, but it was already clear to me how things should work.
Hey Renato,
Yes, you're right. We don't need out users to wait for the actual photo deleted, we can say that it's deleted by kind of "scheduled" it to be deleted in the system. Then later, the messenger will handle that scheduled delete request eventually deleting the file, but it will be a background process, and we don't care how long it will last, the user will get the response almost immediately. Moreover, if something when wrong - we could retry the deleting (or any other process we scheduled).
Also, it's important to understand that with this strategy you don't care about how many simultaneous requests you get the same second because all scheduled deletions will be performed one by one by the Messenger's worker, i.e. no any pick highloads on the server. Without the Messenger, if we know that the process (like deleting a photo from the server) is resource consuming - you may down the whole website when you suddently got a high pick of users requesting file deletions.
So, Messenger clearly has some benefits handling time or resource consuming operations.
And yes, you can have a separate server that will handle all those tasks in the queue if you need, but as I said, thanks to the fact that messenger's worker will handle each queue one by one you can safely do this on the same server as well without causing server overloading. But yes, it depends on your specific case, on how time/resource consuming your operations are, and how many queues you have.
I hope it's clearer to you now.
Cheers!
FANTASTIC!!!!!!!!!!!!!!
YOUR EXPLANATION MADE EVERYTHING CLEAR! THANK YOU SO MUCH
Hey Renato,
Awesome! I am really happy to hear it :)
Cheers!
Great tutorial and followed it step by step using Symfony 6. The "versions" tab explicitly says it will work upto Symfony 5. I'm facing problems with Symfony 6 when changing it to async. Synchronously it works perfectly (dispatch to 1, then dispatch to 2 and on success dispaches to 3 and 4), but in async only the first message is handled succesfully. The message of the 2nd dispatch does not even endup on the queue (Doctrine). Doesn't this work on Symfony 6 ? Should I change to a workflow setup?
"Houston: no signs of life"
Start the conversation!