-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
The catch callback attached to a chain of jobs is called more than once #42883
Comments
This indeed sounds like a bug. Would appreciate any help with figuring this one out. |
My understanding is that the sync queue handles exceptions directly rather than inserting them into the failed_jobs database table:
So one issue is that I only expect the catch callback to be executed once, but also I don't really expect the exception to bubble up if a catch callback is defined, I expect the exception to caught by the callback and maybe only bubble up if the catch callback rethrows it. The same issue applies to batched jobs and I've noticed that the
In the above the catch callback will be called for each job and the finally callback won't be called. Again I expect the catch to only be called once, the finally callback to be called, and like the chained jobs I really expect the catch callback to prevent the exception from bubbling up. Toggling
|
Sent PR #42950 to address this issue |
One of my tests failed with the recent release. I've narrowed the issue down to the For example in the following the
Here is the
I've tested the new fixes on more complicated dispatches. The new fix seems to resolve all the other issues. There are no longer duplicate calls to the catch callbacks and the exceptions no longer bubble up. ✨ 🚀
|
I just noticed something else, if there is an exception in a batch job, is it rolling back the DB after the finally callback? |
I've tested the first snippet you sent here ( #42883 (comment) ) without the changes from #42950 and the finally callback is not called when using the sync connection AND allowing failures. When not allowing failures it works as expected After first inspection it seems to be a different issue, specific to the command bus, but my feeling is the fix might be similar, but I won't have time to further until the weekend. |
Cool. Note that changing There may be one other separate issue too: it looks like the finally call is wrapped in a db transaction so when an exception occurs any changes to db in the finally callback are rolled back. This doesn't happen in other connections like redis. |
Let's create separate issues for the other bugs. Thanks all! |
Does anyone have any ideas on how to resend in #42950 without the breaking change? |
Hi all, it looks like this cannot be solved without introducing a breaking change. Feel free to PR master with the above PR. @bramdevries feel free to provide a comment on that PR if you want to advocate against a breaking change. |
Any good workaround until then? |
@amcsi I didn't test it, but maybe using the |
@rodrigopedra I don't think that would be good. Wouldn't that cache the function call for the whole duration of the queue worker? So if the failure callback is called, and then a different job chain runs and fails, it would not call the callback to handle the failure. |
@amcsi I was thinking about something like this: Bus::chain([
new ProcessPodcast,
new OptimizePodcast,
new ReleasePodcast,
])->catch(function (Throwable $e) {
return once(function () use ($e) {
// logic here
});
})->dispatch(); Then it would only cache upon first usage. If an exception is thrown, the chain should stop processing, right? From my understanding about this issue, the callback was called immediately after first failure, and then again when bailing the batch, which using |
@rodrigopedra except that I dispatch chain both within a daemon queue worker, and also Octane, where multiple "requests" are done in the same process/CLI run. |
The As Of course, it is best to test it before using it in production. |
Description:
The
catch
callback attached to a chain of jobs is called more than once when using thesync
connection. I expected the catch callback to only be called once. It's only called once for the redis and sqs queue connection. This is best illustrated as an example.The above chain will call catch 4 times.
The further down the exception the more times catch will be called for example if the exception at index 4 catch will be called 5 times, if it's at index 5 it will be called 6 times, etc.
Steps To Reproduce:
Here is an isolated console command to test it:
The text was updated successfully, but these errors were encountered: