Overview Managing real-time game logic requires a delicate balance between immediate response and scheduled automation. This implementation uses Laravel Queues to drive a Telegram bingo bot. Instead of relying on traditional cron jobs which lack granular timing, we utilize delayed dispatching and self-perpetuating jobs to handle game phases like player registration and number drawing. This approach ensures the server remains responsive while background workers handle the heavy lifting of game state management. Prerequisites To implement this pattern, you should be comfortable with: * **Laravel Framework**: Basic understanding of Services and Controllers. * **Queue Workers**: Knowledge of how to run `php artisan queue:work`. * **Telegram Bot API**: Familiarity with webhooks and command handling. * **Database Management**: Experience with migrations and basic CRUD operations. Key Libraries & Tools * Laravel Queues: The core engine for background job execution. * Filament: An admin panel used to trigger game sessions and configure parameters. * Laravel Forge: Used for server management and maintaining the queue worker process. * **Database Driver**: The chosen queue driver for persistence and reliability. Code Walkthrough The Initial Delay When a game starts, we dispatch a job to close the registration window after a specific interval. ```php // In GameLifeCycleService.php CompleteJoinPeriod::dispatch($game)->delay(now()->addSeconds($game->join_seconds)); ``` This line instructs the queue to wait exactly $X$ seconds before moving the game from 'joining' to 'active' status. Recursive Self-Dispatching Once the game is active, the `DrawNumber` job handles the logic of pulling a number and then queues its own successor. ```php public function handle() { // 1. Draw and notify $this->drawAndSendMessage(); // 2. Check termination condition if ($this->game->draws->count() >= 75) { return; // Stop the cycle } // 3. Self-dispatch with delay self::dispatch($this->game->fresh()) ->delay(now()->addSeconds(5)); } ``` By calling `self::dispatch()` within the `handle` method, the job creates a loop. It executes, waits 5 seconds, and executes again until 75 numbers are drawn or a player claims bingo. Syntax Notes * **Fresh Models**: Always use `$model->fresh()` when dispatching to ensure the next job has the most recent database state. * **Delay Method**: The `delay()` helper accepts a `DateTime` or `Carbon` instance to set execution timing. * **Termination Returns**: Simply returning from the `handle` method without dispatching prevents the next cycle from starting. Practical Examples * **Auction Countdowns**: Triggering a "Going once, going twice" sequence after a bid. * **Drip Campaigns**: Sending a series of onboarding emails spaced 24 hours apart. * **Status Monitoring**: Checking an external API status every minute until a specific result returns. Tips & Gotchas * **Queue Workers**: Ensure your queue worker is running as a daemon. On Laravel Forge, set up a process to keep the worker active. * **Database Locks**: When multiple jobs or webhooks might update the same game record (like a `/bingo` command during a draw), use `lockForUpdate()` to prevent race conditions. * **Memory Leaks**: Since these jobs can loop many times, avoid heavy static caching within the job class.
Laravel Queues
Products
- Mar 16, 2026
- Nov 22, 2025