Skip to content

Ensure celery tasks execute once #2242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 14, 2025
Merged

Ensure celery tasks execute once #2242

merged 5 commits into from
May 14, 2025

Conversation

shanbady
Copy link
Contributor

@shanbady shanbady commented May 9, 2025

What are the relevant tickets?

Closes https://github.com/mitodl/hq/issues/7276

Description (What does it do?)

Since we moved to EKS, there are potentially multiple celery containers running - each with their own celery beat. By default there is no locking mechanism to ensure that only a single instance of a scheduled task is run. This PR integrates "celery redbeat" as a celery beat scheduler which resolves that issue and ensures only a single task is run regardless of the number of celery beat instances.

How can this be tested?

  1. checkout main
  2. in docker-compose.yml - copy the celery service but rename it to “celery2”
  celery2:
    extends:
      file: docker-compose.apps.yml
      service: celery
    env_file:
      - path: env/shared.env
      - path: env/shared.local.env
        required: false
      - path: env/backend.env
      - path: env/backend.local.env
        required: false
      - path: .env
        required: false
  1. Add a test task that prints the current minute in vector_search/tasks.py
@app.task
def test_task():
    import datetime
    now = datetime.datetime.now()
    print(f"test task called - {now.minute}")
  1. in main/settings_celery.py - add the test task to CELERY_BEAT_SCHEDULE so that it executes every 30 seconds:
    "test-task-every-30s": {"task": "vector_search.tasks.test_task", "schedule": 30}
  2. restart celery and bring up the duplicate celery server docker compose down celery redis then docker compose up -d
  3. ensure you have a "celery" and "celery2" app running via docker compose ps
  4. check your logs and note that every 30 seconds you get 2 tasks outputting test task called - {current minute}
  5. checkout this branch shanbady/integrate-celery-redbeat
  6. rebuild your containers to pull in the new celery-redbeat package docker compose build web celery
  7. re-init your celery and web containers. - make sure you still have the test task in place as well as the celery2 service definition in docker compose from the first set of steps docker compose down celery celery2 web and docker compose up -d
  8. note that only a single instance of the task is outputted

Copy link

github-actions bot commented May 9, 2025

OpenAPI Changes

Show/hide No detectable change.

Unexpected changes? Ensure your branch is up-to-date with main (consider rebasing).

@shanbady shanbady marked this pull request as ready for review May 9, 2025 17:08
@shanbady shanbady added the Needs Review An open Pull Request that is ready for review label May 9, 2025
@mbertrand mbertrand self-assigned this May 14, 2025
Copy link
Member

@mbertrand mbertrand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works great! 👍

@mbertrand mbertrand added Waiting on author and removed Needs Review An open Pull Request that is ready for review labels May 14, 2025
@shanbady shanbady merged commit 195b2ef into main May 14, 2025
13 checks passed
@shanbady shanbady deleted the shanbady/redbeat branch May 14, 2025 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants