aequasi/cron-bundle
Symfony bundle for registering and running recurring tasks via annotated Console Commands. Scan commands with cron:scan, then execute due jobs with cron:run. Uses DateInterval specs (e.g., PT1H) and works with a system cron to trigger runs periodically.
Installation
Run composer require aequasi/cron-bundle "~1.0.0" to add the bundle to your project.
Register the bundle in AppKernel.php:
new Aequasi\Bundle\CronBundle\AequasiCronBundle(),
First Use Case: Define a Cron Job
Create a Symfony command (e.g., app/console make:command MyCronJob).
Annotate it with @Cron to define its schedule:
use Aequasi\Bundle\CronBundle\Annotation\Cron;
class MyCronJob extends ContainerAwareCommand
{
/**
* @Cron("*/5 * * * *")
*/
protected function configure()
{
$this->setName('my:cronjob');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// Your logic here
}
}
Scan and Run Scan for annotated commands:
app/console cron:scan
Execute all scheduled jobs:
app/console cron:run
System Cron Setup
Add a system cron job to trigger cron:run at your desired interval (e.g., */5 * * * * for every 5 minutes).
Command-Based Scheduling
@Cron to define schedules (e.g., */10 * * * * for hourly)./**
* @Cron("0 * * * *") // Run at the start of every hour
*/
protected function configure() { ... }
Dependency Injection
ContainerAwareCommand or constructor injection.class MyCronJob extends ContainerAwareCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->getContainer()->get('my.service')->doWork();
}
}
Logging and Output
OutputInterface to log job execution:
$output->writeln('Job executed at ' . new \DateTime());
app/console cron:run > /var/log/cron.log 2>&1
Dynamic Scheduling
$schedule = $this->getContainer()->getParameter('cron.schedule.myjob');
/**
* @Cron($schedule)
*/
Webhook Integration
cron:run as a web endpoint (e.g., via Symfony’s HttpKernel) for cloud cron services (e.g., AWS CloudWatch Events, Cron-job.org).Database Cleanup
/**
* @Cron("0 3 * * *") // Run daily at 3 AM
*/
protected function configure() { ... }
External API Polling
/**
* @Cron("*/15 * * * *") // Every 15 minutes
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$client = $this->getContainer()->get('http_client');
$client->request('GET', 'https://api.example.com/data');
}
Event-Driven Triggers
Environment-Specific Scheduling
# config.yml
parameters:
cron.schedules:
myjob_dev: "* * * * *"
myjob_prod: "0 * * * *"
Schedule Parsing Errors
*/9 * * * *) will silently fail. Validate schedules using libraries like cron-expression.private function isValidCron(string $expression): bool {
return CronExpression::isValidExpression($expression);
}
Overlapping Executions
cron:run is triggered before the previous execution finishes.LockFactory) or ensure idempotency.Time Zone Issues
config.yml:
framework:
timezone: UTC
Missing cron:scan
cron:scan means annotated commands won’t be registered.composer.json:
"scripts": {
"post-install-cmd": [
"php app/console cron:scan"
]
}
Symfony 3+ Compatibility
ContainerAwareCommand → Command with DI).Dry Runs
app/console cron:scan --env=test
app/console cron:run --env=test --dry-run
Logging
app/console cron:run --env=dev
Manual Triggering
app/console my:cronjob
Idempotent Design
Rate Limiting
sleep() in commands to avoid hitting API rate limits:
sleep(60); // Wait 1 minute between retries
Environment Variables
$apiKey = getenv('MY_API_KEY');
Custom Annotations
@Cron annotation to add metadata (e.g., priority, timeout):
/**
* @Cron(expression="*/5 * * * *", priority=10)
*/
Monitoring
Fallback for Missed Runs
$lastRun = $this->getLastRunTime();
if ($lastRun < $expectedRunTime) {
// Execute logic for missed window
}
How can I help you explore Laravel packages today?