romanfedorskij / cron
Non-blocking cron scheduler with forked PHP workers
Requires
- php: ^8.2
- ext-ctype: *
- ext-pcntl: *
- ext-posix: *
- dragonmantank/cron-expression: ^3.6
- psr/clock: ^1.0
- psr/container: ^1.1 || ^2.0
- psr/log: ^3.0
- revolt/event-loop: ^1.0
- symfony/console: ^6.4 || ^7.4
- symfony/yaml: ^7.4
Requires (Dev)
- buggregator/trap: ^1.16.1
- friendsofphp/php-cs-fixer: ^3.95.27
- phpstan/phpstan: ^2.3.1
- phpstan/phpstan-strict-rules: ^2.1
- phpyh/coding-standard: ^2.6.3
- rector/rector: ^2.7
- testo/assert: ^0.1.17
- testo/test: ^0.1.8
- testo/testo: ^0.10.55
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-10 11:37:05 UTC
README
Подключаемая PHP-библиотека для запуска cron-задач в отдельных fork-процессах. Master использует Revolt для неблокирующего ожидания таймеров и сигналов, а блокирующая работа выполняется только внутри child-worker.
Зачем это ставить
Библиотека полезна, когда приложению нужно:
- держать один long-running scheduler вместо отдельного процесса cron на каждую задачу;
- описывать расписания fluent API, атрибутами, YAML или обычным crontab;
- выбирать независимые планы
dev,stage,prodили серверные профили; - получать свежий PSR-11 container scope и новые подключения на каждый запуск;
- последовательно запускать одноразовые шаги только после exit code
0; - ограничивать пересечения и общее число одновременно работающих процессов;
- находить ошибки callable и конфигурации до запуска event loop.
Что предоставляет библиотека
| Возможность | Для чего нужна | Подробности |
|---|---|---|
| Fluent schedule API | everyMinutes(), dailyAt(), weekdays() без ручного cron |
Scheduling и profiles |
| Configuration loaders | Manual API, attributes, YAML и классический crontab | Configuration sources |
| Symfony Console tasks | Именованные arguments/options через InputInterface без callback-обёрток |
Symfony Console tasks |
| Guided migration | Готовый Codex skill для переноса cron реального приложения | Application migration |
| Success chains | Одноразовые callable, service, static, container и exec шаги | Task chains |
| PSR-11 integration | Новый container scope внутри каждого child-worker | Container contract |
| Preflight validation | Ошибки карты и callable до регистрации задач | Configuration validation |
| Revolt runtime | Таймеры, сигналы и неблокирующий master process | Runtime |
| Worker bootstrap | Явная композиция loaders и приложения в bin/cron.php |
Application worker |
| Crontab conversion | Перенос crontab -l в управляемый YAML |
Configuration sources |
Общая модель
manual / attributes / YAML / crontab
|
v
CronProfileMap
|
v
preflight validation
|
v
Revolt scheduler master
|
v
forked task process
|
exit code == 0
|
v
next one-shot task
Расписание принадлежит только корневой задаче. Шаги then*() не получают
собственный cron и ставятся во внутреннюю очередь лишь после успешного
завершения предыдущего процесса.
Что остаётся на стороне приложения
Библиотека планирует и исполняет задачи, но не заменяет framework, DI container или process supervisor. Приложение определяет:
- какие команды и services существуют;
- как создаётся свежий PSR-11 container;
- какой профиль активен на конкретном runtime;
- где хранятся YAML/crontab файлы;
- как scheduler запускается и перезапускается через systemd, Docker или supervisor;
- куда отправляются lifecycle-логи.
Как читать документацию
- Quick start — первый ручной scheduler.
- Configuration sources — выбор loader-а и profiles.
- Symfony Console tasks — input, container, chain и troubleshooting.
- Application migration — перенос существующих cron-задач с помощью skill.
- Task chains — service/static/container pipelines.
- Application worker — полный
bin/cron.php. - Runtime — fork, Revolt, overlap и shutdown.
- Configuration validation — fail-fast контракт.
Установка
composer require romanfedorskij/cron
Требования:
- PHP
^8.2на Unix-like системе; ext-pcntlиext-posix;- Revolt event loop;
- PSR-11 container нужен для service/container и Symfony Console задач.
Quick start
<?php declare(strict_types=1); use Wolfcharaa\Cron\Runtime\SchedulerOptions; use Wolfcharaa\Cron\Scheduler; require __DIR__ . '/vendor/autoload.php'; $scheduler = new Scheduler( new SchedulerOptions( maxConcurrency: 4, profile: 'default', timezone: 'Europe/Moscow', ), ); $scheduler ->task('cleanup', static function (): int { // Код выполняется в child-worker и не блокирует master event loop. return 0; }) ->everyMinutes(5) ->weekdays() ->withoutOverlapping(); $scheduler->run();
Полный разбор: docs/guides/quick-start.md.
Chain quick start
$scheduler ->serviceTask('import', ImportCommand::class, 'run') ->everyMinutes(15) ->thenStatic('reindex', SearchIndex::class, 'rebuild', ['products']) ->thenContainer( 'notify', [PipelineCallbacks::class, 'notify'], ['operations'], );
Static callback для thenContainer() получает container и context перед
настроенными аргументами:
public static function notify( ContainerInterface $container, TaskExecutionContext $context, string $channel, ): int { return 0; }
В атрибутах те же шаги задаются через StaticTaskConfig,
ContainerTaskConfig и SymfonyCommandTaskConfig. См.
полный пример attribute pipeline и
Symfony Console tasks.
Документация по разделам
Guides
Reference
Examples
- Application worker
- Attribute pipeline
- Исполняемые PHP-заготовки находятся в
examples/.
Разработка
make check make test-php-matrix
Матрица проверяет PHP 8.2–8.5 с минимально допустимыми и последними совместимыми версиями зависимостей. Один вариант можно запустить отдельно:
make test-php-version PHP_VERSION=8.4 DEPENDENCY_MODE=lowest