ScheduleWorkCommand.php
TLDR
This file contains the ScheduleWorkCommand
class, which is a command for starting the schedule worker. It executes scheduled tasks every minute.
Classes
ScheduleWorkCommand
The ScheduleWorkCommand
class extends the Command
class and represents a command for starting the schedule worker. It has the following properties:
-
$signature
: The name and signature of the console command. -
$description
: The console command description.
The class has a handle
method that executes the console command. It performs the following tasks:
- Prints an info message.
- Sets the initial values for the variables
$lastExecutionStartedAt
and$executions
. - Builds the command to run the
schedule:run
command and updates it with the output redirection if specified. - Enters an infinite loop that performs the following steps:
- Sleeps for 100 milliseconds.
- Checks if the current time is the start of a new minute and if the last execution didn't start at the same time. If true, it:
- Creates a new
Process
object for the command. - Starts the process.
- Updates the value of
$lastExecutionStartedAt
.
- Creates a new
- Iterates over the running executions and:
- Gets the incremental output and error output of the process.
- Writes the output to the console.
- Removes the execution from the list of running executions if it has finished.
<?php
namespace Illuminate\Console\Scheduling;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Illuminate\Support\ProcessUtils;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
#[AsCommand(name: 'schedule:work')]
class ScheduleWorkCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'schedule:work {--run-output-file= : The file to direct <info>schedule:run</info> output to}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Start the schedule worker';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$this->components->info(
'Running scheduled tasks every minute.',
$this->getLaravel()->isLocal() ? OutputInterface::VERBOSITY_NORMAL : OutputInterface::VERBOSITY_VERBOSE
);
[$lastExecutionStartedAt, $executions] = [Carbon::now()->subMinutes(10), []];
$command = implode(' ', array_map(fn ($arg) => ProcessUtils::escapeArgument($arg), [
PHP_BINARY,
defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan',
'schedule:run',
]));
if ($this->option('run-output-file')) {
$command .= ' >> '.ProcessUtils::escapeArgument($this->option('run-output-file')).' 2>&1';
}
while (true) {
usleep(100 * 1000);
if (Carbon::now()->second === 0 &&
! Carbon::now()->startOfMinute()->equalTo($lastExecutionStartedAt)) {
$executions[] = $execution = Process::fromShellCommandline($command);
$execution->start();
$lastExecutionStartedAt = Carbon::now()->startOfMinute();
}
foreach ($executions as $key => $execution) {
$output = $execution->getIncrementalOutput().
$execution->getIncrementalErrorOutput();
$this->output->write(ltrim($output, "\n"));
if (! $execution->isRunning()) {
unset($executions[$key]);
}
}
}
}
}