laravel / horizon

Dashboard and code-driven configuration for Laravel queues.
https://laravel.com/docs/horizon
MIT License
3.88k stars 658 forks source link

In some cases, the callback for the Bus::batch()->then() method is never being executed. #1512

Closed buglinjo closed 4 weeks ago

buglinjo commented 4 weeks ago

Horizon Version

5.24.5

Laravel Version

10.48.12

PHP Version

8.3.13

Redis Driver

PhpRedis

Redis Version

7.2.6

Database Driver & Version

MySQL 8.4.3

Description

Jobs in Kubernetes infrastructure get stuck in the reserved (pending) state when pods are killed.

This issue occurs periodically when deploying new changes or when Horizon pods are terminated.

It appears that jobs stuck in the pending state are retried exactly retry_after param value seconds (the value set in config/queue.php retry_after) after the reserved_at epoch stored in Redis.

Additionally, if a job is stuck in the pending state, it seems that the ->then(callback) callback function is no longer being executed. Consequently, the batch is completed, but the callback responsible for finalizing everything is never triggered.

We urgently require a solution to address this issue. How can we ensure that if a pending job finally executes after 21 minutes, the ->then(callback) callback function is executed?

Steps To Reproduce

To reproduce this problem, follow these steps:

  1. Create a batch with multiple jobs and assign a unique identifier to each job to indicate its position in the queue.
  2. Start the Horizon service.
  3. Terminate the Horizon service before the batch is completed processing.
  4. Restart the Horizon service and wait until all batch jobs are executed.
  5. You will observe a few jobs stuck in the pending state. These are the jobs that were being executed but never completed due to the Horizon shutdown.
  6. Wait retry_after value seconds with the Horizon service active, and you will see that those pending jobs are executed.
  7. You will also notice that the ->then(callback) callback method is not being executed.