tinker: PendingDispatch never dispatches if not assigned to a variable in Tinker

This inconsistency took me a while to wrap my head around.

>>> dispatch(new App\Jobs\TestJob)
=> Illuminate\Foundation\Bus\PendingDispatch {#1328}
>>> exit

Expected: PendingDispatch is dispatched when the object is destructed. Actual: Doesn’t dispatch.

>>> $pending = dispatch(new App\Jobs\TestJob)
=> Illuminate\Foundation\Bus\PendingDispatch {#1328}
>>> exit

This will dispatch.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 11
  • Comments: 16 (4 by maintainers)

Most upvoted comments

Closing since this isn’t a bug, it’s just how dispatch works.

Appreciate this isn’t a bug as such, but still a poorly documented (missing from release notes?) breaking change in behaviour. Fine once you know, but sucky until you find out the hard way.

use Illuminate\Contracts\Bus\Dispatcher;
app(Dispatcher::class)->dispatch($command);

This is definitely a gotcha. What was the reason behind the change?

I agree. I think this is a time suck for developers trying to figure out why this isn’t executing. What steps can we take to alleviate this?

This is a known subtlety, but not actually a bug. If you want the laravel 5.4 behaviour on laravel 5.5, then you’ll need to call dispatch directly on the bus object.

If @robclancy’s approach launches two jobs for you, try this instead:

app(\Illuminate\Contracts\Bus\Dispatcher::class)->dispatch(new \App\Jobs\MyCustomJob());

In my apps, I define the following, which is a fire and forget, but is not reliant on garbage collection for dispatch to actually happen.

if (!function_exists('execute')) {
    /**
     * Send the given command to the dispatcher for execution.
     *
     * @param object $command
     *
     * @return void
     */
    function execute($command)
    {
        app(Dispatcher::class)->dispatch($command);
    }
}

app(\Illuminate\Contracts\Bus\Dispatcher::class)->

Is kinda annoying to write every time, interestingly enough wrapping the pending job in a dd() executes it.

dd(SomeJob::dispatch())

or if your job doesn’t use the Dispatchable trait

dd(dispatch(new SomeJob()))

For people coming here you can just destruct the object you get.

App\Jobs\SendTasksDigest::dispatch(App\User::find(5))->__destruct();

I continually run into this. It’s very frustrating.

@GrahamCampbell a bug is “just how code works”. if this behaviour is unfavourable, it’s a bug.