dispatchNow
Just call the jobs handle method and return its results.
Doesn't matter if jobs implements ShouldQueue or use the Queuable trait. You can even use the return of the job's handle method in the current thread.
For me the biggest disadvantage of this is if an exception is thrown from the job's handle method, its failed method won't be called, so you need to handle the exception (for loggine purposes, for example) in the scope the job was dispatched.
dispatchSync
If job implements the ShouldQueue interface it will be processed by the queue pipeline in the same thread/process. But it will run through the same pipeline as any other queued job.
For example, if the job uses the Queuable trait, you can have job middlewares, and also rely on the failed method when an exception occurs in the handle method.
I personally start using this to make my synchronous jobs more consistent with the other jobs. Also, if you use job middleware and rely on the job's failed method to handle exceptions, you don't need to worry if those would called when dispatching to a async queue or to the sync connection.
Sample
To illustrate you can try this in your project's ./routes/web.php file:
class MyJob implements \Illuminate\Contracts\Queue\ShouldQueue
{
use \Illuminate\Bus\Queueable;
private string $name;
private bool $shouldFail;
public function __construct(string $name, bool $shouldFail)
{
$this->name = $name;
$this->shouldFail = $shouldFail;
}
public function middleware()
{
return [
function ($job, $next) {
\dump('middleware: ' . $this->name);
return $next($job);
},
];
}
public function handle()
{
if ($this->shouldFail) {
throw new \RuntimeException($this->name);
}
return 'result: ' . $this->name;
}
public function failed(\Throwable $exception)
{
\dump('from failed: ' . $exception->getMessage());
}
}
Route::get('test', function (\Illuminate\Contracts\Bus\Dispatcher $dispatcher) {
$result = $dispatcher->dispatchNow(new MyJob('now', false));
\dump('results from request: ' . $result);
\dump('============================');
try {
$dispatcher->dispatchNow(new MyJob('now/failing', true));
} catch (\Throwable $exception) {
\dump('exception from request: ' . $exception->getMessage());
}
\dump('============================');
$result = $dispatcher->dispatchSync(new MyJob('sync', false));
\dump('results from request: ' . $result);
\dump('============================');
try {
$dispatcher->dispatchSync(new MyJob('sync/failing', true));
} catch (\Throwable $exception) {
\dump('exception from request: ' . $exception->getMessage());
}
});
The results should be:
"results from request: result: now"
"============================"
"exception from request: now/failing"
"============================"
"middleware: sync"
"results from request: 0"
"============================"
"middleware: sync/failing"
"exception from failed: sync/failing"
"exception from request: sync/failing"
As we can see, for the same job when using dispatchNow the middleware was not executed and the failed method was not called when it failed. But the return from the handle method is available for usage on the request.
While when using dispatchSync, both middleware and failed method were executed as expected. But the return from the handle method is not available in the request.
===
Note: if the job does not use the Queueable trait, the return of the handle method will be available to the request when using dispatchSync. I don't know if it is by design.
Regarding if the dispatchNow will be deprecated in favor of dispatchSync, I guess there is a chance, because only the newer one is in the docs right now.