nirvair
nirvair

Reputation: 4180

Schedule multiple crons in Laravel

I am trying to run multiple jobs in Laravel at different times. This is the code:

protected function schedule(Schedule $schedule)
{
    $schedule->command('emails:send')->dailyAt('08:00');
    $schedule->command('emails:evening-status')->dailyAt('17:00');
    $schedule->command('email:weekly-report')->weekly()->mondays()->at('08:00');
}

The problem here is that only the first command emails:send works. The other commands don't work at the specified time. However, when I run them manually they work fine.

What is it that I am missing?

Upvotes: 24

Views: 23457

Answers (8)

Dani Fadli
Dani Fadli

Reputation: 383

It's been 4 years since this question added, but I hope my answer still can help anyone. In my case (adapted from your case), I just added some conditional cases with the Carbon package from Laravel in my Kernel.php.

In my case, I want to run 3 schedulers. Two schedulers will run once every Monday at 8 AM and 5 PM and one else will run once every day. And this is how I make the condition.

public function schedule(Schedule $schedule)
{
   if(Carbon::now()->format('N') == '1')  //check if today is Monday
   {
      if(Carbon::now()->format('G') == '8')  //check if now is 8 AM
      {
         $schedule->command('first:command')->everyMinute();
      }
      if(Carbon::now()->format('G') == '17') //check if now is 5 PM
      {
         $schedule->command('second:command')->everyMinute();
      }
   }

   $schedule->command('another:command')->dailyAt('08:00')->withoutOverlapping();
}

Then, you can set up your cron job in the server to run hourly. The another:command schedule will not run 24 times a day because I have added the withoutOverlapping() method, and it only will run at 8 AM. See this laravel docs about scheduling and this PHP docs about date-time format if necessary.

Upvotes: 1

Raheel Hasan
Raheel Hasan

Reputation: 6023

Similar situation, except that I am calling a method for each cron using call, for example:

$schedule->call('\App\Http\Controllers\comm\commCron::abc');
$schedule->call('\App\Http\Controllers\comm\commCron::xyz');

I had the same problem, later realised first cron was calling an exit at some point of error.

So please make sure none of the crons retuls in exit or die(). Just return false instead (if you need to).

Upvotes: 2

Sam Killen
Sam Killen

Reputation: 51

I think you may need to look at your actual server cron configuration. Laravel scheduler requires the server cron to be run every minute for all schedules to run at the desired time. You may just have the cron running at 8.00am every day instead of every minute.

It may be worth a check, I know I had difficulty with the same issue when I first started scheduling.

When using the scheduler, you only need to add the following Cron entry to your server. If you do not know how to add Cron entries to your server, consider using a service such as Laravel Forge which can manage the Cron entries for you:

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

This Cron will call the Laravel command scheduler every minute. When the schedule:run command is executed, Laravel will evaluate your scheduled tasks and runs the tasks that are due.

Upvotes: 2

AP-
AP-

Reputation: 19

We ran intro similar issues when using Laravel's built-in scheduling module.

In our case, the first command was silently failing and preventing the subsequent scheduled commands from being run.

As a quick test, try changing the order of the commands such that emails:send is at the bottom and see if that works. In general, catch any Exceptions that may be thrown and it should fix the issue.

Upvotes: 0

meisam masomi
meisam masomi

Reputation: 63

if you need use Laravel Schedule Use This code

    $schedule = new Schedule();
    $schedule->command('emails:send')
             ->dailyAt('08:00')->withoutOverlapping();

    $schedule = new Schedule();
    $schedule->command('emails:evening-status')
             ->dailyAt('17:00')->withoutOverlapping();

    $schedule = new Schedule();
    $schedule->command('email:weekly-report')
             ->weekly()->mondays()->at('08:00')->withoutOverlapping();

but may be this way is wrong, advise to use Laravel artisan Command and put that cammand on host cron jobs

Upvotes: -1

AddWeb Solution Pvt Ltd
AddWeb Solution Pvt Ltd

Reputation: 21681

You can try below code:

protected function schedule(Schedule $schedule)
{
        $schedule->command('emails:send')
                 ->dailyAt('08:00')->withoutOverlapping();

        $schedule->command('emails:evening-status')
                 ->dailyAt('17:00')->withoutOverlapping();

        $schedule->command('email:weekly-report')
                 ->weekly()->mondays()->at('08:00')->withoutOverlapping();
}

Above code just execute without overlapped. You can get more idea about prevent overlapping.

Let me know if you still facing same.

Upvotes: 0

Rikal
Rikal

Reputation: 225

Use queue for job processing

on cron, add all jobs to queue

Run multiple queue workers

Upvotes: 0

fico7489
fico7489

Reputation: 8560

If second comand is not working:

$schedule->command('emails:evening-status')
             ->dailyAt('17:00');

you can insert only one line of code that print current date in some file eg. "test.txt" then check in wanted time if file is created. If file is created you can conclude that something if wrong with code in script that is scheduled.

Upvotes: 0

Related Questions