laravel / lumen-framework

The Laravel Lumen Framework.
https://lumen.laravel.com
MIT License
1.47k stars 418 forks source link

Can not schedule queue jobs #733

Closed Korri closed 6 years ago

Korri commented 6 years ago

Description:

Queuing jobs in Lumen throws error Call to a member function onQueue() on integer but the job is still queued.

If the job does not implement ShouldQueue, it's worse as the Scheduler is trying to call dispatch_now() which does not exists on Lumen: Call to undefined function Illuminate\Console\Scheduling\dispatch_now()

Steps To Reproduce:

  1. Queue a job that implements Illuminate\Contracts\Queue\ShouldQueue for example:
    $schedule->job(new ExampleJob())->everyMinute();
  2. Run it using php artisan schedule:run

Example repository: https://github.com/Korri/lumen-schedule-job/commit/ab64a7b0d5036d8caaf4c99d2beab7e7ffdd78f3

emil-nasso commented 6 years ago

I experienced this problem too. It can be worked around by dispatching jobs like this:

        $schedule->call(function () {
            $job = (new HelloWorldJob())->onQueue('cron');
            dispatch($job);
        }
        )->description("hello world")->everyMinute();

The problem seems to be that there is a difference between the dispatch helper in laravel and lumen. The laravel variant returns an object but the lumen on doesn't.

This is the line causing it: https://github.com/illuminate/console/blob/master/Scheduling/Schedule.php#L99

If you call onQueue on the job instead of on the result of dispatch it seem to work in lumen.

richardbporter commented 6 years ago

I'm having this issue as well. Any plans on fixing this for Lumen?

simonhamp commented 6 years ago

This is also an issue in Lumen 5.5 (LTS)

simonhamp commented 6 years ago

You can of course make all jobs synchronous by setting QUEUE_DRIVER=sync in your .env file.

But if you want some jobs to be synchronous (i.e. removing the implements ShouldQueue statement) without causing problems, you'll need to add the dispatch_now method from Laravel to your global namespace somehow.

I personally prefer to create a helpers.php, put this chunk in there and autoload it via my composer.json.

This should really be in Lumen's helpers.php as it's a dependency in Illuminate\Console\Scheduling\Schedule.

To stop the error appearing on the queued jobs is a bit more complicated. In Laravel, dispatch proxies jobs through a PendingDispatch class which is what's returned from the dispatch helper (in Laravel). But it's not available in Lumen, partly because Illuminate\Foundation isn't available as a subtree split.

I'm not clear why this class is in Illuminate\Foundation and not in Illuminate\Bus (where it would make more sense IMHO). If it was in Illuminate\Bus then dispatch in Lumen could match its Laravel counterpart and the world would be right again.

driesvints commented 6 years ago

This is indeed a bug which should be fixed. Welcoming PR's for this. Short term solution is probably to add a dispatch_now helper to the Lumen helpers.php file.

simonhamp commented 6 years ago

@driesvints not sure if a single PR can cover this... it really feels like Illuminate\Foundation needs to be available to Lumen or PendingDispatch moves to Illuminate\Bus, but I guess the implications of both of those solutions are further reaching than I'm aware of.

jensdenies commented 6 years ago

I made a PR to make the scheduler compatible with Lumen.

driesvints commented 6 years ago

Thanks @JacksonIV!

simonorups commented 1 year ago

I had the same issue in lumen 8.x today. I was queuing using dispatch(new ExampleJob); so after spending some good time googling with no success, I decided to replaced dispatch(new ExampleJob); withQueue::push(new ExampleJob);. My vscode code editor threw unknown class error so I added use Illuminate\Support\Facades\Queue; at the top of the class then jobs started queuing fine. For more details refer to Dispatching Jobs section. I hope this helps someone out there.