|
28 | 28 | import rq.job |
29 | 29 |
|
30 | 30 | from django.conf import settings |
| 31 | +from rq.registry import StartedJobRegistry |
31 | 32 |
|
32 | 33 | from grimoirelab_toolkit.datetime import datetime_utcnow |
33 | 34 |
|
@@ -154,7 +155,15 @@ def _is_job_removed_or_stopped(job: Job, queue: str) -> bool: |
154 | 155 | try: |
155 | 156 | connection = django_rq.get_connection(queue) |
156 | 157 | job_rq = rq.job.Job.fetch(job.uuid, connection=connection) |
157 | | - return job_rq.get_status() in RQ_JOB_STOPPED_STATUS |
| 158 | + status = job_rq.get_status() |
| 159 | + if status == rq.job.JobStatus.STARTED: |
| 160 | + # Sometimes, the worker may be forcibly stopped, leaving the job |
| 161 | + # in the STARTED status. We need to check if the job has expired |
| 162 | + # due to a missing heartbeat. |
| 163 | + expiration_date = StartedJobRegistry(queue, connection).get_expiration_time(job_rq) |
| 164 | + return expiration_date < datetime.datetime.now() |
| 165 | + else: |
| 166 | + return status in RQ_JOB_STOPPED_STATUS |
158 | 167 | except rq.exceptions.NoSuchJobError: |
159 | 168 | return True |
160 | 169 |
|
@@ -228,6 +237,7 @@ def _schedule_job( |
228 | 237 |
|
229 | 238 | job.status = SchedulerStatus.ENQUEUED |
230 | 239 | task.status = SchedulerStatus.ENQUEUED |
| 240 | + job.scheduled_at = scheduled_at |
231 | 241 | task.scheduled_at = scheduled_at |
232 | 242 | except Exception as e: |
233 | 243 | logger.error(f"Error enqueuing job of task {task.task_id}. Not scheduled. Error: {e}") |
|
0 commit comments