-
Notifications
You must be signed in to change notification settings - Fork 440
Symfony. Async event dispatching #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@makasim this looks really good, actually! Thanks for the heads up.
I'm looking if I could reuse mechanics from this for my Doctrine event converter: https://gist.github.com/dkarlovi/4a3c9f0ec01d98f8d75bce46d0df38f6 (new version).
BTW this is my Symfony user token thing: https://gist.github.com/dkarlovi/4971003ab1d42ec2871c8bd33589f007
BTW this is my Symfony user token thing
Looks good. You can send a PR with such an extension If you willing to contribute.
I'll ask you for tests and a few small corrections.
Sure, I'll try to get it for the weekend, thanks.
-
The real listener is replaced by async one (it sends a message)
screenshot 2017年05月17日 12 28 12 -
The message is sent:
screenshot 2017年05月17日 12 30 42 -
Async processor listens to the topic on default queue:
screenshot 2017年05月17日 13 15 28 -
Messages dispatched in consumer:
screenshot 2017年05月17日 13 17 12 screenshot 2017年05月17日 12 33 43
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixes #90
@makasim do I understand the code correctly: you're pushing the events at the end of the request?
I've just stumbled upon a race condition with my code where in 5% of the time my consumer gets the event before the producer does a Doctrine flush()
(and can't find the entity to process). The order at which this is dispatched (regarding other listeners) is important here, should take into account, it should be very late in the process, probably almost the last thing.
@dkarlovi The entity must already be in the database If you do post a message on postXXX
Doctrine's event.
(this isn't related to this PR directly, sorry)
I'm using ApiPlatform to build an API app. They ship with a listener which does a flush()
for you. Doctrine will trigger the event listeners when you do a persist()
, NOT when you do a flush()
(which makes sense, I guess). Problem is, my handlers get invoked before flush()
which I assumed cannot happen because lazy = true
in Enqueue config (my assumption was lazy=true
does the same thing Swiftmailer does).
Timeline:
Doctrine::persist()
Doctrine::postPersist()
listeners (which, in my case, dispatches a Enqueue message)Doctrine::flush()
(which actually stores to database)
In my case, 2) & 3) are competing which will be done first and I'm consistently getting a failure (which means, RabbitMQ "won").
Might be a good idea to create an in-memory message spool and flush it at request end, much like Swiftmailer Bundle does?
@dkarlovi shouldn't you subscribe on the right event which is triggered after the models are persisted to db? Like postFlush
event.
postFlush is called at the end of EntityManager#flush(). EntityManager#flush() can NOT be called safely inside its listeners.
@makasim you might be right, will look into it, if it provides the same information postXXX() listeners get, I don't see why not.
Missed the onTerminate item on the TODO, awesome. 👍 You're really building great piece of tech here, thanks a lot for your effort.
@makasim will I be able to use this onTerminate
message dispatcher when just sending messages regularly, without having an event listener?
@makasim will I be able to use this onTerminate message dispatcher when just sending messages regularly, without having an event listener?
Sure, use enqueue.spool_producer
and you are done.
The code was released as a standalone package https://github.com/php-enqueue/async-event-dispatcher the doc is here https://github.com/php-enqueue/enqueue-dev/blob/master/docs/bundle/async_events.md
Symfony. Async event dispatching
Uh oh!
There was an error while loading. Please reload this page.
Install the bundle and then enable
async_events
(If you do not enable it, events will be processed as usual).To add async listener you have to add
async: true
attribute to the tag, like this:and of course you must have a consumer running:
The listener is not executed in the same process but instead, a message is sent to MQ and dispatched in a consumer.
TODO:
(削除) Support event_subscribers (削除ここまで)Symfony async events. Support event subscribers. #94(削除) Add a asyncTransformer attribute support to event_listener tag. (削除ここまで)That was not implmeneted, isntead there is ability to set eventName on transformer tag as regexp.