Add separate cron runner that doesn't use proc_open (#1405)

* Add alternative to using the artisan schedule runner

* StyleCI fixes

* Add additional cron time periods

* Style fixes

* Typo

* Update the web cron to use the new system

* Write out JSON for which tasks were run

* Rename cron.php to just cron
This commit is contained in:
Nabeel S
2022-02-11 16:24:06 -05:00
committed by GitHub
parent 607ea6f5e5
commit 78fd8367a1
20 changed files with 337 additions and 35 deletions

View File

@@ -22,7 +22,11 @@ class ProcessQueue extends Command
'--stop-when-empty' => null,
]);
Log::info(Artisan::output());
$jobOutput = trim(Artisan::output());
if (!empty($jobOutput)) {
Log::info($jobOutput);
}
///** @var App\Support\WorkCommand $queueWorker */
//$queueWorker = new App\Support\WorkCommand(app('queue.worker'), app('cache.store'));

90
app/Console/Cron.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
/**
* This runs any of the cron tasks that are set to run according to the Laravel schedule
*/
namespace App\Console;
use App\Console\Cron\FifteenMinute;
use App\Console\Cron\FiveMinute;
use App\Console\Cron\Hourly;
use App\Console\Cron\JobQueue;
use App\Console\Cron\Monthly;
use App\Console\Cron\Nightly;
use App\Console\Cron\ThirtyMinute;
use App\Console\Cron\Weekly;
use App\Contracts\Command;
use Illuminate\Console\Scheduling\Schedule;
class Cron
{
/** @var Schedule */
private $scheduler;
/**
* @var string[] The cron tasks which get called/run
*/
private $cronTasks = [
JobQueue::class,
FiveMinute::class,
FifteenMinute::class,
ThirtyMinute::class,
Hourly::class,
Nightly::class,
Weekly::class,
Monthly::class,
];
/**
* @var array Stores the instantiated cron tasks
*/
private $cronRunners = [];
/**
* @param Schedule $scheduler
*/
public function __construct(Schedule $scheduler)
{
$this->scheduler = $scheduler;
foreach ($this->cronTasks as $task) {
/** @var Command $cronTask */
$cronTask = app($task);
$signature = $cronTask->getSignature();
if (empty($signature)) {
continue;
}
$this->cronRunners[$signature] = $cronTask;
}
}
/**
* Try to figure out which commands are supposed to run right now
*
* @return array string of tasks that were run
*/
public function run(): array
{
$events = $this->scheduler->dueEvents(app());
if (empty($events)) {
return [];
}
$run = [];
/** @var \Illuminate\Console\Scheduling\Event $event */
foreach ($events as $event) {
foreach ($this->cronRunners as $signature => $task) {
if (!str_contains($event->command, $signature)) {
continue;
}
$task->callEvent();
$run[] = $signature;
}
}
return $run;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Events\CronFifteenMinute;
/**
* The actual cron tasks are in app/Cron
*/
class FifteenMinute extends CronCommand
{
protected $signature = 'cron:fifteen';
protected $description = 'Run the 15 minute cron tasks';
protected $schedule;
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
event(new CronFifteenMinute());
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Events\CronFiveMinute;
/**
* This just calls the CronNightly event, so all of the
* listeners, etc can just be called to run those tasks
*
* The actual cron tasks are in app/Cron
*/
class FiveMinute extends CronCommand
{
protected $signature = 'cron:five';
protected $description = 'Run the 5 minute cron tasks';
protected $schedule;
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
event(new CronFiveMinute());
}
}

View File

@@ -2,14 +2,14 @@
namespace App\Console\Cron;
use App\Contracts\Command;
use App\Contracts\CronCommand;
use App\Events\CronHourly;
/**
* This just calls the CronHourly event, so all of the
* listeners, etc can just be called to run those tasks
*/
class Hourly extends Command
class Hourly extends CronCommand
{
protected $signature = 'cron:hourly';
protected $description = 'Run the hourly cron tasks';
@@ -17,7 +17,11 @@ class Hourly extends Command
public function handle(): void
{
$this->redirectLoggingToFile('cron');
$this->callEvent();
}
public function callEvent()
{
event(new CronHourly());
}
}

View File

@@ -2,14 +2,14 @@
namespace App\Console\Cron;
use App\Contracts\Command;
use App\Contracts\CronCommand;
use Illuminate\Support\Facades\Artisan;
/**
* This just calls the CronHourly event, so all of the
* listeners, etc can just be called to run those tasks
*/
class JobQueue extends Command
class JobQueue extends CronCommand
{
protected $signature = 'cron:queue';
protected $description = 'Run the cron queue tasks';
@@ -17,9 +17,16 @@ class JobQueue extends Command
public function handle(): void
{
$this->redirectLoggingToFile('cron');
Artisan::call('queue:cron');
$this->callEvent();
$this->info(Artisan::output());
$queueOutput = trim(Artisan::output());
if (!empty($queueOutput)) {
$this->info($queueOutput);
}
}
public function callEvent()
{
Artisan::call('queue:cron');
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Console\Cron;
use App\Contracts\Command;
use App\Contracts\CronCommand;
use App\Events\CronMonthly;
/**
@@ -11,7 +11,7 @@ use App\Events\CronMonthly;
*
* The actual cron tasks are in app/Cron
*/
class Monthly extends Command
class Monthly extends CronCommand
{
protected $signature = 'cron:monthly';
protected $description = 'Run the monthly cron tasks';
@@ -19,7 +19,11 @@ class Monthly extends Command
public function handle(): void
{
$this->redirectLoggingToFile('cron');
$this->callEvent();
}
public function callEvent()
{
event(new CronMonthly());
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Console\Cron;
use App\Contracts\Command;
use App\Contracts\CronCommand;
use App\Events\CronNightly;
/**
@@ -11,7 +11,7 @@ use App\Events\CronNightly;
*
* The actual cron tasks are in app/Cron
*/
class Nightly extends Command
class Nightly extends CronCommand
{
protected $signature = 'cron:nightly';
protected $description = 'Run the nightly cron tasks';
@@ -19,7 +19,11 @@ class Nightly extends Command
public function handle(): void
{
$this->redirectLoggingToFile('cron');
$this->callEvent();
}
public function callEvent()
{
event(new CronNightly());
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Console\Cron;
use App\Contracts\CronCommand;
use App\Events\CronThirtyMinute;
/**
* The actual cron tasks are in app/Cron
*/
class ThirtyMinute extends CronCommand
{
protected $signature = 'cron:thirty';
protected $description = 'Run the 30 minute cron tasks';
protected $schedule;
public function handle(): void
{
$this->callEvent();
}
public function callEvent()
{
event(new CronThirtyMinute());
}
}

View File

@@ -2,7 +2,7 @@
namespace App\Console\Cron;
use App\Contracts\Command;
use App\Contracts\CronCommand;
use App\Events\CronWeekly;
/**
@@ -11,7 +11,7 @@ use App\Events\CronWeekly;
*
* The actual cron tasks are in app/Cron
*/
class Weekly extends Command
class Weekly extends CronCommand
{
protected $signature = 'cron:weekly';
protected $description = 'Run the weekly cron tasks';
@@ -19,7 +19,11 @@ class Weekly extends Command
public function handle(): void
{
$this->redirectLoggingToFile('cron');
$this->callEvent();
}
public function callEvent()
{
event(new CronWeekly());
}
}

View File

@@ -2,10 +2,13 @@
namespace App\Console;
use App\Console\Cron\FifteenMinute;
use App\Console\Cron\FiveMinute;
use App\Console\Cron\Hourly;
use App\Console\Cron\JobQueue;
use App\Console\Cron\Monthly;
use App\Console\Cron\Nightly;
use App\Console\Cron\ThirtyMinute;
use App\Console\Cron\Weekly;
use App\Services\CronService;
use Illuminate\Console\Scheduling\Schedule;
@@ -33,10 +36,16 @@ class Kernel extends ConsoleKernel
->withoutOverlapping();
}
/*
* NOTE: IF MORE TASKS ARE ADDED, THEY ALSO MUST BE ADDED TO THE CRON.PHP
*/
$schedule->command(FiveMinute::class)->everyFiveMinutes();
$schedule->command(FifteenMinute::class)->everyFifteenMinutes();
$schedule->command(ThirtyMinute::class)->everyThirtyMinutes();
$schedule->command(Nightly::class)->dailyAt('01:00');
$schedule->command(Hourly::class)->hourly();
$schedule->command(Weekly::class)->weeklyOn(0);
$schedule->command(Monthly::class)->monthlyOn(1);
$schedule->command(Hourly::class)->hourly();
// When spatie-backups runs
/*if (config('backup.backup.enabled', false) === true) {