course-hero/symfony-cron-bundle
Installation:
composer require course-hero/symfony-cron-bundle
Enable the bundle in config/bundles.php:
return [
// ...
SymfonyCronBundle\SymfonyCronBundle::class => ['all' => true],
];
Basic Configuration (in config/packages/symfony_cron.yaml):
symfony_cron:
lock_service: SymfonyCronBundle\Component\Lock\LockFileService
process_service: SymfonyCronBundle\Component\Process\ProcessService
First Use Case: Create a command to run via cron:
php bin/console make:command DailyReport
Then configure it in config/cron.yml (or via YAML/annotation):
commands:
app:daily-report:
schedule: "0 0 * * *" # Runs daily at midnight
lock_service: "@symfony_cron.lock_file_service"
Locking Strategies:
LockFileService for simple file-based locks (default).MemcachedLockService or RedisLockService for distributed environments:
services:
symfony_cron.lock_memcached_service:
class: SymfonyCronBundle\Component\Lock\MemcachedLockService
arguments: ["@memcached.client"]
Process Isolation:
ProcessService to avoid orphaned locks:
use SymfonyCronBundle\Component\Process\ProcessService;
class DailyReportCommand extends Command {
protected function execute(InputInterface $input, OutputInterface $output) {
$processService = $this->get('symfony_cron.process_service');
$processService->run(function() {
// Your job logic here
});
}
}
Dynamic Scheduling:
use SymfonyCronBundle\Annotation\Cron;
/**
* @Cron(schedule="0 3 * * 1") // Every Monday at 3 AM
*/
class WeeklyBackupCommand extends Command { ... }
Event-Driven Triggers:
EventDispatcher for pre/post-execution hooks:
services:
app.cron.event_listener:
class: App\EventListener\CronEventListener
tags:
- { name: kernel.event_listener, event: cron.job.start, method: onJobStart }
Lock Timeouts:
symfony_cron:
lock_ttl: 1800 # 30 minutes
var/cron-locks/ (default path).Process Leaks:
ProcessService mandatorily to fork processes:
$processService->run(function() {
// Job code here
}, ['timeout' => 3600]); // Optional timeout
Symfony 4+ Compatibility:
autoconfigure: true in config/packages/framework.yaml.services.yml with config/services.yaml.Cron Expression Parsing:
CronExpression class:
use SymfonyCronBundle\Component\Cron\CronExpression;
$expression = new CronExpression('0 0 * * *');
if (!$expression->isValid()) {
throw new \RuntimeException('Invalid cron expression');
}
Logging:
monolog:
handlers:
cron:
type: stream
path: "%kernel.logs_dir%/cron.log"
level: debug
Testing:
LockService and ProcessService in PHPUnit:
$lockService = $this->createMock(LockServiceInterface::class);
$lockService->method('lock')->willReturn(true);
$this->container->set('symfony_cron.lock_file_service', $lockService);
Custom Lock Backends:
AbstractLockService for databases or custom storage:
class DatabaseLockService extends AbstractLockService {
protected function getLockKey($jobName) {
return "cron_lock_{$jobName}";
}
// Implement lock/unlock logic
}
Environment-Specific Scheduling:
%kernel.environment% in cron expressions:
commands:
app:cleanup:
schedule: "0 2 * * *" # Prod only
env: prod
How can I help you explore Laravel packages today?