Skip to content
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

[8.x] Allow queueing application and service provider callbacks while callbacks are already being processed #39175

Merged

Conversation

reneroth
Copy link

As of now, queueing a terminating-callback while the application is already in the termination process will simply cause the callback to be lost silently, possibly resulting in hard to trace bugs. Same holds true for the application booting and booted callbacks, as well as for the service provider callbacks of the same name.
This is problematic, since Job dispatching is using the terminating callbacks internally and nested afterResponse Jobs will not work.

This PR aims to fix this issue by allowing those callbacks to be added while the callback queue is already being processed.

Real Life Usage

We are developing an app that sends notifications to the users, utilising many different kind of Jobs. One Job is responsible for sending Push notifications, which is dispatched directly in a controller. It is also dispatched from another Job, tasked with handling the results of certain user interactions. Dispatching Jobs from other Jobs works fine in Laravel and I see nothing in the documentation that indicates this usage is not supported.
When we attempted to decrease the load on our queue handler, we switched both Jobs to use Job::dispatchAfterResponse / dispatch($job)->afterResponse(). Since this uses something along the lines of app()->terminating($job->dispatchNow) internally, any nested Jobs did not run.

Solution

By switching the foreach loop to a while loop doing a count on every iteration, we gain the ability to add to our callback stack while processing it. This comes at a slight performance penalty - a naive test of using both methods to iterate over an array of 100,000 entries on my development machine showed the new method to be around 15% / 0.5ms slower. In real world applications, with no more than a few dozen callbacks - realistically something between zero and slightly more than zero 😁 - the performance difference will be no more than at maximum a 1/100th of a millisecond.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants