Skip to content

Instantly share code, notes, and snippets.

@robbydooo
Last active October 23, 2021 14:14
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save robbydooo/65bf341ea0f4081150b945bfb1d38d3c to your computer and use it in GitHub Desktop.
Save robbydooo/65bf341ea0f4081150b945bfb1d38d3c to your computer and use it in GitHub Desktop.
Heroku Laravel Scheduler
<?php
/**
This Scheduler will run once every minute unlike the Heroku scheduler which only runs every 10 mintues.
To use this scheduler with Laravel 5.4+ add this file to /app/Console/Commands/RunScheduler.php
Register this file in app/Console/Kernel.php
protected $commands = [
...
Commands\RunScheduler::class
...
]
Add this line to your Procfile:
scheduler: php -d memory_limit=512M artisan schedule:cron
Push to Heroku and you will see you have a new dyno option called Scheduler, start ONE only.
I highly recommend using Artisan::queue to run your cron jobs so that your scheduler does not over run.
*/
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
use Illuminate\Support\Facades\Artisan;
/**
*
* Runs the scheduler every 60 seconds as expected to be done by cron.
* This will break if jobs exceed 60 seconds so you should make sure all scheduled jobs are queued
*
* Class RunScheduler
* @package App\Console\Commands
*/
class RunScheduler extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'schedule:cron {--queue}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Run the scheduler without cron (For use with Heroku etc)';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Waiting '. $this->nextMinute(). ' for next run of scheduler');
sleep($this->nextMinute());
$this->runScheduler();
}
/**
* Main recurring loop function.
* Runs the scheduler every minute.
* If the --queue flag is provided it will run the scheduler as a queue job.
* Prevents overruns of cron jobs but does mean you need to have capacity to run the scheduler
* in your queue within 60 seconds.
*
*/
protected function runScheduler()
{
$fn = $this->option('queue') ? 'queue' : 'call';
$this->info('Running scheduler');
Artisan::$fn('schedule:run');
$this->info('completed, sleeping..');
sleep($this->nextMinute());
$this->runScheduler();
}
/**
* Works out seconds until the next minute starts;
*
* @return int
*/
protected function nextMinute()
{
$current = Carbon::now();
return 60 -$current->second;
}
}
@relativokobe
Copy link

Hi, so how am i gonna use this? i have my own schedulers. how do i use your code for my schedulers. Im a newbie btw

@robbydooo
Copy link
Author

Hi, so how am i gonna use this? i have my own schedulers. how do i use your code for my schedulers. Im a newbie btw

Sorry i completely missed this message. Hopefully you have figured it out by now :-).

See my message here for full details https://stackoverflow.com/questions/35151297/how-to-setup-laravel-5s-task-scheduling-in-heroku/42682908?noredirect=1#comment80872368_42682908

@regis-fontaine
Copy link

Thank's for this solution! It works like a charm!

For future users, I really recommend using {--queue } in your Procfile.
And for Heroku users, don't forget about active your resource in the Heroku Dashboard ^^

Thank's again @robbydooo !

@arisawali2014
Copy link

arisawali2014 commented Sep 23, 2021

is this work on Heroku free dynos?

anyone know how to adding worker:run to the scheduler?

@robbydooo
Copy link
Author

I do not believe you can on free dynos, although it has been a long time since I last used this code sorry.

@arisawali2014
Copy link

I do not believe you can on free dynos, although it has been a long time since I last used this code sorry.

i've been tried it on free dynos. it works.

@robbydooo
Copy link
Author

nice!

@Virus5600
Copy link

Virus5600 commented Oct 22, 2021

I'm completely new to schedulers so I'm somewhat confused on how to implement this and run my scheduled tasks at the Kernel.php of my code. Do I have to move them from the Kernel@schedule to the RunScheduler@runScheduler function or do I just need to call something to run my tasks at the Kernel.php? Also, what does the Artisan::$fn('schedule:run'); does?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment