4

I have a schedule like this:

<?php

namespace App\Console;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Console\Scheduling\Schedule;
protected function schedule(Schedule $schedule)
{
   Artisan::call('queue:work');
}

I add this on my cronjob:

* * * * * cd /var/www/html/my_script_address && php artisan schedule:run

Is it correct code? I am asking, because every minute run Artisan::call('queue:work').

Is it the best way?

codewitharefin
  • 1,398
  • 15
  • 24
paranoid
  • 6,799
  • 19
  • 49
  • 86
  • 1
    queue:work is supposed to be ran by supervisor, not schedule. But in this way you can add queue:work --once to the schedule, it may be fine – Laraleg Dec 24 '18 at 09:53
  • -- once is not good idea because I use send email with job and when I have 10 email It takes 10 minutes and this is not good – paranoid Dec 24 '18 at 09:57
  • Don't use it like this. Run `php artisan queue:listen` or `php artisan queue:work` from console. It will continue to work until interruption. --once might be a good idea to consider like this. Because queue:work is not a run and finish type of code. It takes a very long `while`. @Laraleg +1 for supervisor – Hilmi Erdem KEREN Dec 24 '18 at 11:39

4 Answers4

7

Your queue worker should be running on its own. You should use supervisor to make sure it stays running. However, if you must start the queue worker from the scheduler it is probably best to use queue:work --stop-when-empty

Adam Martinez
  • 81
  • 1
  • 5
4

I wanted to write a long answer with explanation.

1- Crontab is a scheduled job manager. It calls your command every time the scheduler ticks.

eg: If you create a crontab entry to write hello world once in a minute, it will do it every minute, and to the eternity.

2- Queue worker listens to the queue and it works if there is any job awaiting to be done. Very similar to cron jobs, but the execution time is not predefined. See it yourself:

/**
 * Listen to the given queue in a loop.
 *
 * @param  string  $connectionName
 * @param  string  $queue
 * @param  \Illuminate\Queue\WorkerOptions  $options
 * @return void
 */
public function daemon($connectionName, $queue, WorkerOptions $options)
{
    // [...]
    while (true) {
        ...
    }
}

As you see, she continues until something from the outside world stops her.

4- Your scheduler will create one more worker like this every minute.


Use something like supervisor to watch your workers. And create your worker instances thoughtfully. See supervisor configuration part of laravel documentation.

If you insist to use cron and queue workers together, use queue:work --once to let your worker know when to stop :)

Hilmi Erdem KEREN
  • 1,949
  • 20
  • 29
1

If you just want to run schedule job, just write in `app/console/kernel.php``:

protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        // Do something
        DB::table('recent_users')->delete();
    })->daily();
}

And Put below code to /etc/cron.d/laravel-project:

* * * * * cd /path/to/laravel-project-root && php artisan schedule:run >> /dev/null 2>&1

See: https://laravel.com/docs/5.7/scheduling#introduction


The Queue is provide to run asynchronous task, you can install supervisor to keep queue:work is always running.

See this doc and configure queue:work and supervisor, and use schedule task to dispatch your job to queue. Modify app/console/kernel.php:

protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        // Do something
        App\MyScheduleJob::dispatch();
    })->daily();
}

Now, queue should always running, and schedule job can dispatch to queue everyday.

Calos
  • 1,783
  • 19
  • 28
1

as per documentation https://laravel.com/docs/5.8/scheduling#scheduling-queued-jobs

you can simply queue a job via:

$schedule->job(new Heartbeat)->everyFiveMinutes();
wired00
  • 13,930
  • 7
  • 70
  • 73