Skip to content

Instantly share code, notes, and snippets.

@ghostwriter
Last active April 18, 2026 17:59
Show Gist options
  • Select an option

  • Save ghostwriter/9fa848ec1292a11beaedb891f2b0ef16 to your computer and use it in GitHub Desktop.

Select an option

Save ghostwriter/9fa848ec1292a11beaedb891f2b0ef16 to your computer and use it in GitHub Desktop.
Schedule a task based on the specified CRON expression in PHP with Event loops ("dragonmantank/cron-expression" and "revolt/event-loop")
<?php
declare(strict_types=1);
use Revolt\EventLoop;
use Cron\CronExpression;
require implode(DIRECTORY_SEPARATOR, [dirname(__DIR__), 'vendor', 'autoload.php']);
/**
* Schedule the given task based on the specified CRON expression
*
* "dragonmantank/cron-expression" and "revolt/event-loop"
*
* e.g.
*
* schedule('* * * * *', static function (int $now = 0) {
* echo date('Y-m-d H:i:s', $now) . ": Task {$now} running\n\n";
* });
*
* @param callable $task
* @param CronExpression|string $cron
*/
function schedule(CronExpression|string $cron, callable $task, DateTimeImmutable $now = new DateTimeImmutable()): void
{
$cron = match (true) {
is_string($cron) => new CronExpression($cron),
default => $cron,
};
if ($cron->isDue($now)) {
EventLoop::defer(static fn () => $task($now->getTimestamp()));
}
EventLoop::delay(
$cron->getNextRunDate($now)->getTimestamp() - $now->getTimestamp(),
static fn () => schedule($cron, $task)
);
}
EventLoop::run();
// Run example task every minute:
// schedule('* * * * *', static function (int $now = 0) {
// echo implode(' ', [
// date('Y-m-d H:i:s', $now),
// 'Memory usage:',
// number_format(memory_get_usage() / 1024, 3).'K' . PHP_EOL,
// ]) . \PHP_EOL;
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment