In Laravel 6.0 job middleware was introduced. This works perfectly, except for when jobs are dispatched to be executed immediately using dispatch_now() or Job::dispatchNow(). Job specific middleware is never applied, as the \Illuminate\Bus\Dispatcher::dispatchNow() method never resolves the command specific middleware as the \Illuminate\Queue\CallQueuedHandler::dispatchThroughMiddleware() does.
class MyJobWithMiddleware implements ShouldQueue
{
public function middleware()
{
return [new MyMiddleware()];
}
public function handle()
{
//
}
}
class MyMiddleware
{
public function handle($command, $next)
{
dd('call me');
}
}
dispatch_now(new MyJobWithMiddleware());
//
dispatch(new MyJobWithMiddleware());
// "call me"
Seems like more of a feature request since the pull request explicitly states that the middleware is for queued jobs. https://github.com/laravel/framework/pull/29391#issue-303858409
Heya, see the answer by @devcircus above.
Wow. But why? Sometimes I want to execute a job immediately, but always I want to execute the middleware.
This is not good. middleware should always be executed.
The same problem!
@driesvints What can we do about this?
I found workaround:
SomeJob::dispatch($arg1, $arg2, ...)->onConnection('sync');
As this issue has been re-opened, will there be a way to ignore any job middleware when a job is being called with dispatchNow()?
The documentation uses a rate limiter middleware as an example. When calling a job with dispatchNow() you very likely want to ignore any rate limit.
Is there a way to determine if a job has been called with dispatchNow()?
Taylor sent in a PR here: https://github.com/laravel/framework/pull/32559
A new dispatchSync method is available in upcoming 8.x.
Most helpful comment
A new
dispatchSyncmethod is available in upcoming 8.x.