Skip to content

Instantly share code, notes, and snippets.

@robbydooo
Last active October 23, 2021 14:14
Show Gist options
  • 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;
}
}
@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