bytespin/console-command-scheduler-bundle
Installation:
composer require bytespin/console-command-scheduler-bundle
Register the bundle in config/bundles.php (automatically handled by Composer).
Configure Scheduler:
Add a YAML config file at config/packages/console_command_scheduler.yaml:
console_command_scheduler:
commands:
app:send_emails:
schedule: '0 12 * * *' # Cron syntax
timezone: 'Europe/Paris'
max_runtime: 3600 # Max execution time in seconds
First Use Case:
Schedule a command (e.g., app:send_emails) by defining it in the config above. Run the scheduler worker:
php bin/console console-command-scheduler:run
Verify:
Check the database (console_command_scheduler_command table) and logs (var/log/console_command_scheduler.log) for execution records.
Define Commands:
Configure commands in console_command_scheduler.yaml with cron syntax, timezones, and runtime limits.
console_command_scheduler:
commands:
app:backup_database:
schedule: '0 3 * * 0' # Weekly on Sunday at 3 AM
timezone: 'UTC'
max_runtime: 7200
Run the Scheduler: Use the CLI command to execute scheduled tasks:
php bin/console console-command-scheduler:run
For production, set up a cron job (e.g., * * * * * php /path/to/bin/console console-command-scheduler:run).
Integrate with EasyAdmin (Optional):
If using EasyAdmin, register the Command entity in your admin dashboard:
// src/Admin/CommandAdmin.php
use Bytespin\ConsoleCommandSchedulerBundle\Entity\Command;
class CommandAdmin extends AbstractCrudController
{
public static function getEntityFqcn(): string { return Command::class; }
}
Event-Driven Extensions: Listen to events for custom logic (e.g., notifications):
// src/EventListener/CommandEventListener.php
use Bytespin\ConsoleCommandSchedulerBundle\Event\CommandEvent;
class CommandEventListener
{
public function onCommandExecuted(CommandEvent $event): void
{
if ($event->getCommand()->getReturnCode() !== 0) {
// Send alert
}
}
}
Register the listener in services.yaml:
services:
App\EventListener\CommandEventListener:
tags:
- { name: 'kernel.event_listener', event: 'console_command_scheduler.command.executed' }
Notifications:
Extend the notification system by implementing Bytespin\ConsoleCommandSchedulerBundle\Notification\NotificationInterface:
class SlackNotification implements NotificationInterface
{
public function notify(Command $command): void
{
// Send Slack message
}
}
Register it in services.yaml:
services:
App\Notification\SlackNotification:
tags: ['console_command_scheduler.notification']
Database Schema Updates:
1.0.13+), always run:
php bin/console doctrine:schema:update --force
Timezone Mismatches:
timezone in your config matches the server’s timezone to avoid scheduling conflicts.TZ=Europe/Paris php bin/console console-command-scheduler:run if unsure.Max Runtime Enforcement:
max_runtime setting forcefully terminates commands exceeding the limit. Avoid long-running commands without proper error handling.EasyAdmin Dependency:
EasyCorp/EasyAdminBundle. If not installed, the Command entity won’t be accessible via the dashboard.composer require easycorp/easy-admin-bundle
Cron Syntax Errors:
schedule: '0 12 * * *' # Correct (runs daily at 12 PM)
schedule: '0 12 * *' # Incorrect (missing day-of-week)
Logging Overrides:
var/log/console_command_scheduler.log. To customize the logger:
# config/packages/monolog.yaml
services:
Bytespin\ConsoleCommandSchedulerBundle\Logger\CommandLogger:
arguments:
$logger: '@monolog.logger.console_command_scheduler'
Check Execution Logs:
var/log/console_command_scheduler.log for errors or execution details.APP_DEBUG=1) for verbose output.Dry Run:
max_runtime: 0 (commands will start but terminate immediately).Event Debugging:
php bin/console debug:event-dispatcher
console_command_scheduler events to verify listeners are attached.Database Inspection:
console_command_scheduler_command table to verify records:
SELECT * FROM console_command_scheduler_command ORDER BY executed_at DESC;
Custom Command Metadata:
Command entity to store additional metadata (e.g., priority, environment_vars):
// src/Entity/ExtendedCommand.php
#[ORM\Entity]
class ExtendedCommand extends Command
{
#[ORM\Column]
private ?int $priority = 0;
// Add getters/setters
}
Command entity mapping in config/packages/doctrine.yaml if needed.Dynamic Scheduling:
CommandScheduler service to fetch schedules dynamically (e.g., from an API):
services:
Bytespin\ConsoleCommandSchedulerBundle\Scheduler\CommandScheduler:
arguments:
$commandRepository: '@app.custom_command_repository'
Parallel Execution:
Messenger component to run commands in parallel (requires additional setup):
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
Retries for Failed Commands:
CommandExecutor:
class RetryCommandExecutor implements CommandExecutorInterface
{
public function execute(Command $command): int
{
$retries = 3;
while ($retries--) {
$returnCode = $this->originalExecutor->execute($command);
if ($returnCode === 0) return $returnCode;
sleep(10); // Delay between retries
}
return $returnCode;
}
}
services.yaml:
services:
Bytespin\ConsoleCommandSchedulerBundle\Executor\CommandExecutor:
class: App\Executor\RetryCommandExecutor
How can I help you explore Laravel packages today?