Add acks_late to ETL tasks killed by worker autoscaling scale-downs - #3678
Merged
Conversation
OpenAPI ChangesNo changes detected Unexpected changes? Ensure your branch is up-to-date with |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Celery task configuration for a set of scheduled ETL jobs so that if a worker is terminated mid-run (e.g., Kubernetes autoscaling scale-down), tasks are not lost and can be redelivered by the broker and complete on another worker.
Changes:
- Add
acks_late=Trueandreject_on_worker_lost=Trueto selected scheduled ETL tasks inlearning_resources,news_events, andvector_search. - Align these tasks’ acknowledgment behavior with existing late-ack + worker-lost rejection patterns already present elsewhere in the codebase (e.g., other
vector_searchtasks).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
learning_resources/tasks.py |
Marks several scheduled ETL tasks as late-ack + requeue-on-worker-loss to prevent silent loss on worker termination. |
news_events/tasks.py |
Applies late-ack + requeue-on-worker-loss to key scheduled news/event ETL tasks. |
vector_search/tasks.py |
Applies late-ack + requeue-on-worker-loss to the scheduled sync_topics task to improve resilience to worker scale-downs. |
shanbady
self-requested a review
July 27, 2026 14:01
Celery worker pods are routinely SIGTERM'd by autoscaling scale-downs minutes after the top-of-hour beat burst, killing scheduled ETL tasks mid-run. With default early acks the broker message is already gone, so the task is never redelivered and silently stays STARTED forever. 7-day production logs show get_learning_resource_views never completed once (49/49 runs lost), get_content_files lost 321 runs, and every news_events ETL lost 15-20% of runs. Add acks_late=True + reject_on_worker_lost=True (the existing pattern on get_ocw_courses, get_youtube_data, etc., which demonstrably recover via broker redelivery) to the affected idempotent ETL tasks and the same-shaped daily getters that share the top-of-hour race window. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mbertrand
force-pushed
the
mb/etl-task-acks-late
branch
from
July 27, 2026 16:15
9e5bb5f to
8d7dfe8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What are the relevant tickets?
Fixes #3677
Description (What does it do?)
Adds
acks_late=True, reject_on_worker_lost=Trueto the scheduled ETL tasks that production logs show are being lost when celery worker pods are terminated by autoscaling scale-downs mid-run (details and 7-day loss counts in the issue). With early acks (celery's default) the broker message is gone the moment the task starts, so a killed run vanishes and stays STARTED forever in the monitoring app. With late acks the broker redelivers the message after the visibility timeout (1 hour) and the run completes on a surviving worker.This matches the pattern already used by
get_ocw_courses,get_youtube_data,summarize_content_files_task, etc., which are killed just as often but demonstrably recover via redelivery.Tasks changed (all idempotent):
learning_resources:get_mitxonline_data,get_mit_edx_data,get_xpro_data,get_content_files,get_podcast_data,get_learning_resource_views,get_mitpe_data,get_sloan_data,get_mit_climate_data,update_next_start_date_and_pricesnews_events:get_medium_mit_news,get_ol_events,get_mitpe_news,get_mitpe_events,get_website_content_newsvector_search:sync_topicsInteraction with
cooldown_task(#3363): unchanged. The cooldown check runs on the worker at execution time regardless of ack mode, andReject(requeue=False)is terminal, so re-triggers during a cooldown window are still dropped. Cooldown locks (900s) expire well before the 1-hour visibility timeout, so a redelivered recovery run is not blocked by its own cooldown. (get_mit_edx_data's 3600s lock ≈ the visibility timeout, so its recovery run can race the lock — worst case it is rejected, which is exactly today's behavior.)How can this be tested?
Verified locally end to end (steps reproducible with
COMPOSE_PROFILES=backend):docker compose up -d celery, then enqueue a run and note the task id:mainthe count for this task is 0 because the message is acked at start:docker kill -s KILL mit-learn-celery-1. The message survives inunacked.docker compose up -d celery). Redelivery normally happens after the 1-hour visibility timeout; to avoid waiting, age the pending entries so the next restore cycle picks them up:Also verify cooldown behavior is preserved: enqueue the same task twice within 900s — the second run logs
Skipping ...: cooldown activeand is rejected without executing.Sanity check that the flags are active:
Additional Context
After deploy, killed runs will show as redelivered-then-succeeded in https://celery-monitoring.odl.mit.edu instead of stuck STARTED. Stuck-STARTED entries from before the deploy won't self-heal; their next scheduled run covers them.