Integration
Schedule Constraints
The scheduler provides many constraint methods to fine-tune when your tasks should run.
Basic Integration
The recommended way to define scheduled tasks is using the event manager during container building:
use Cake\Event\EventManager;
use Scheduling\Schedule;
$eventManager = EventManager::instance();
$eventManager->on('Application.buildContainer', function ($event): void {
$container = $event->getData('container');
$schedule = $container->get(Schedule::class);
// Define your scheduled tasks here
$schedule->command('cache clear')->everyMinute();
});This approach ensures that your scheduled tasks are defined when the application container is built, making them available to all scheduling commands.
Defining Scheduled Tasks
Command Scheduling
Schedule CakePHP console commands using the command method:
// Schedule a command every minute
$schedule->command('emails send')->everyMinute();
// Schedule with arguments
$schedule->command('reports generate --format=pdf')->daily();
// Schedule using command class
$schedule->command(\App\Command\BackupCommand::class)->weekly();Closure Scheduling
Schedule closures for simple tasks:
$schedule->call(function () {
// Clear temporary files
$filesystem = new \Cake\Filesystem\Folder(TMP);
$filesystem->delete();
})->daily();Shell Command Scheduling
Execute system commands:
$schedule->exec('php /path/to/script.php')->hourly();
$schedule->exec('mysqldump -u user -p database > backup.sql')
->dailyAt('02:00');Frequency Options
The plugin provides a comprehensive set of frequency methods:
Second-Based Frequencies
$schedule->command('monitor check')->everySecond();
$schedule->command('health check')->everyFiveSeconds();
$schedule->command('queue process')->everyTenSeconds();
$schedule->command('metrics collect')->everyFifteenSeconds();
$schedule->command('status update')->everyThirtySeconds();Minute-Based Frequencies
$schedule->command('cache warm')->everyMinute();
$schedule->command('data sync')->everyFiveMinutes();
$schedule->command('log rotate')->everyFifteenMinutes();
$schedule->command('cleanup temp')->everyThirtyMinutes();Hour-Based Frequencies
$schedule->command('reports hourly')->hourly();
$schedule->command('backup incremental')->everyTwoHours();
$schedule->command('analytics process')->everyFourHours();Daily Frequencies
$schedule->command('reports daily')->daily();
$schedule->command('backup full')->dailyAt('02:00');
$schedule->command('cleanup logs')->dailyAt('03:30');Weekly and Monthly
$schedule->command('reports weekly')->weekly();
$schedule->command('reports monthly')->monthly();
$schedule->command('maintenance')->weeklyOn(1, '08:00'); // Monday at 8 AMCustom Cron Expressions
$schedule->command('custom task')->cron('0 */6 * * *'); // Every 6 hoursTask Constraints
Time-Based Constraints
// Run only between 9 AM and 5 PM
$schedule->command('business task')
->hourly()
->between('09:00', '17:00');
// Skip execution between midnight and 6 AM
$schedule->command('maintenance task')
->hourly()
->unlessBetween('00:00', '06:00');Day-Based Constraints
// Run only on weekdays
$schedule->command('business report')
->daily()
->weekdays();
// Run only on weekends
$schedule->command('maintenance')
->hourly()
->weekends();
// Run on specific days
$schedule->command('weekly report')
->daily()
->days([1, 3, 5]); // Monday, Wednesday, FridayConditional Constraints
// Run only if condition is true
$schedule->command('conditional task')
->daily()
->when(function () {
return file_exists('/tmp/run_task');
});
// Skip if condition is true
$schedule->command('normal task')
->hourly()
->skip(function () {
return app()->isDownForMaintenance();
});Preventing Task Overlaps
Prevent tasks from running if the previous instance is still executing:
$schedule->command('long running task')
->everyMinute()
->withoutOverlapping();
// Custom overlap timeout (in minutes)
$schedule->command('data import')
->everyFiveMinutes()
->withoutOverlapping(10);Single-Server Execution
Ensure tasks run on only one server in multi-server environments:
$schedule->command('backup database')
->daily()
->onOneServer();
// Named single-server tasks
$schedule->command('process queue high')
->everyMinute()
->onOneServer()
->name('process-high-priority');Background Execution
Run tasks in the background to prevent blocking:
$schedule->command('heavy processing')
->everyFiveMinutes()
->runInBackground();Task Hooks
Before and After Hooks
$schedule->command('data processing')
->hourly()
->before(function () {
// Log task start
\Cake\Log\Log::info('Starting data processing');
})
->after(function () {
// Log task completion
\Cake\Log\Log::info('Data processing completed');
});Success and Failure Hooks
$schedule->command('critical task')
->daily()
->onSuccess(function () {
// Send success notification
\Cake\Log\Log::info('Critical task completed successfully');
})
->onFailure(function () {
// Send failure alert
\Cake\Log\Log::error('Critical task failed');
});Sub-Minute Tasks
The plugin supports sub-minute scheduling for high-frequency tasks:
// Process queue items every 5 seconds
$schedule->command('queue work')
->everyFiveSeconds()
->withoutOverlapping(1);
// Monitor system health every 10 seconds
$schedule->call(function () {
// Check system metrics
})->everyTenSeconds();Repeatable Tasks
For tasks that need to run multiple times within a minute:
$schedule->command('monitor check')
->everyMinute()
->repeatEvery(5); // Repeat every 5 seconds within the minuteEvent Integration
The plugin dispatches events during task execution that you can listen to:
use Cake\Event\EventManager;
use Scheduling\Event\ScheduledTaskStarting;
use Scheduling\Event\ScheduledTaskFinished;
$eventManager = EventManager::instance();
$eventManager->on('Scheduling.taskStarting', function ($event) {
$task = $event->getData('event');
\Cake\Log\Log::info('Task starting: ' . $task->getSummaryForDisplay());
});
$eventManager->on('Scheduling.taskFinished', function ($event) {
$task = $event->getData('event');
$output = $event->getData('output');
\Cake\Log\Log::info('Task finished: ' . $task->getSummaryForDisplay());
});Running the Scheduler
Production Setup
Add a single cron entry to run the scheduler:
* * * * * cd /path/to/your/project && bin/cake schedule run >> /dev/null 2>&1Development Mode
For development, use the work command that runs continuously:
bin/cake schedule workThis command will:
- Run scheduled tasks as they become due
- Handle sub-minute tasks properly
- Provide verbose output for debugging
- Support graceful termination with Ctrl+C
Testing Scheduled Tasks
Test your scheduled tasks without waiting:
# List all scheduled tasks
bin/cake schedule list
# Test a specific task
bin/cake schedule test "cache clear"
# Run all due tasks immediately
bin/cake schedule runConfiguration Options
Timezone Configuration
Set a default timezone for all scheduled tasks:
$schedule->useTimezone('America/New_York');
// Or set per task
$schedule->command('reports generate')
->dailyAt('09:00')
->timezone('Europe/London');Cache Configuration
Configure cache store for task overlap prevention:
$schedule->useCache('redis');Mutex Configuration
Custom mutex implementation for single-server execution:
$schedule->useMutex(new \App\Scheduling\CustomMutex());Task Output
The scheduler provides several convenient methods for working with the output generated by scheduled tasks. First, using the sendOutputTo method, you may send the output to a file for later inspection:
$schedule->command('emails send')
->daily()
->sendOutputTo($filePath);If you would like to append the output to a given file, you may use the appendOutputTo method:
$schedule->command('emails send')
->daily()
->appendOutputTo($filePath);Note The
sendOutputToandappendOutputTomethods are exclusive to thecommandandexecmethods.
Task Hooks
Using the before and after methods, you may specify code to be executed before and after the scheduled task is executed:
$schedule->command('emails send')
->daily()
->before(function () {
// The task is about to execute...
})
->after(function () {
// The task has executed...
});The onSuccess and onFailure methods allow you to specify code to be executed if the scheduled task succeeds or fails. A failure indicates that the scheduled console or system command terminated with a non-zero exit code:
$schedule->command('emails send')
->daily()
->onSuccess(function () {
// The task succeeded...
})
->onFailure(function () {
// The task failed...
});If output is available from your command, you may access it in your after, onSuccess or onFailure hooks by type-hinting a string parameter as the $output argument of your hook's closure definition:
$schedule->command('emails send')
->daily()
->onSuccess(function (string $output) {
// The task succeeded...
})
->onFailure(function (string $output) {
// The task failed...
});Task Monitoring
The Scheduling plugin includes comprehensive monitoring capabilities to track task execution, performance, and status.
Enabling Monitoring
Enable monitoring for individual tasks using the useMonitoring() method:
$schedule->command('emails send')
->daily()
->useMonitoring()
->monitorName('Email Sending Task')
->graceTimeInMinutes(10);Monitoring Configuration
Configure monitoring behavior for tasks:
$schedule->command('data processing')
->hourly()
->useMonitoring()
->monitorName('Data Processing')
->graceTimeInMinutes(30)
->storeOutputInDb(true);Monitoring Methods
| Method | Description |
|---|---|
useMonitoring() | Enable monitoring for this task |
disableMonitoring() | Disable monitoring for this task |
monitorName(string $name) | Set a custom monitor name |
graceTimeInMinutes(int $minutes) | Set grace time for overdue detection |
storeOutputInDb(bool $store) | Enable storing command output in database |
Monitoring Commands
# Sync schedule with monitoring database
bin/cake schedule monitor sync
# List all monitored tasks
bin/cake schedule monitor list
# Filter by status
bin/cake schedule monitor list --status=running
bin/cake schedule monitor list --status=failed
bin/cake schedule monitor list --status=overdue
# Filter by type
bin/cake schedule monitor list --type=cake_command
# Show recent activity
bin/cake schedule monitor list --recent=24
# Output as JSON
bin/cake schedule monitor list --format=json
# Clean up old log data
bin/cake schedule monitor prune --days=7Monitoring Configuration
Configure monitoring behavior in config/scheduling.php:
return [
'Scheduling' => [
'delete_log_items_older_than_days' => 30,
'date_format' => 'Y-m-d H:i:s',
'grace_time_in_minutes' => 5,
'store_output_in_db' => false,
],
];Events
The scheduler dispatches a variety of events during the scheduling process. You may define listeners for any of the following events:
| Event Name |
|---|
Scheduling\Event\ScheduledTaskStarting |
Scheduling\Event\ScheduledTaskFinished |
Scheduling\Event\ScheduledTaskSkipped |
Scheduling\Event\ScheduledTaskFailed |
You may register event listeners for these events in your application's event manager:
use Cake\Event\EventManager;
use Scheduling\Event\ScheduledTaskStarting;
use Scheduling\Event\ScheduledTaskFinished;
$eventManager = EventManager::instance();
$eventManager->on('Scheduling.taskStarting', function ($event) {
$task = $event->getData('event');
\Cake\Log\Log::info('Task starting: ' . $task->getSummaryForDisplay());
});
$eventManager->on('Scheduling.taskFinished', function ($event) {
$task = $event->getData('event');
$output = $event->getData('output');
\Cake\Log\Log::info('Task finished: ' . $task->getSummaryForDisplay());
});This integration guide covers all major features of the Scheduling plugin. For detailed API documentation, see the API Reference.