Skip to content

Auto-refresh zoom tokens via celery task + implement task locks#1652

Open
devmount wants to merge 19 commits into
mainfrom
enhancements/1580-auto-refresh-zoom-tokens
Open

Auto-refresh zoom tokens via celery task + implement task locks#1652
devmount wants to merge 19 commits into
mainfrom
enhancements/1580-auto-refresh-zoom-tokens

Conversation

@devmount
Copy link
Copy Markdown
Collaborator

@devmount devmount commented Apr 24, 2026

What changed?

This change implements a celery task that triggers a command to check all Zoom token expiry dates. If a token is expired or under a given time threshold, a token refresh is triggered by initializing the OAuth2 Session and making a lightweight get_me() call.

A new env var ZOOM_TOKEN_TTL_IN_SECONDS got introduced to specify, how long we assume an auth token to be valid before checking and renewing it.

If there is an error during the process, the external connection is marked with status = error so that at least it is shown up in the UI. Otherwise, it is marked as status = ok.

Also, we've added some repository functions for external connection token and status handling.

Why?

This improvement should help users reducing manual effort to keep a Zoom connection active.

Limitations and Notes

Added a comment with a TODO that we should proactively send an email to the Subscriber in case there's a problem with renewing the token: #1662

How to test

Run docker compose exec backend run-command main refresh-zoom-tokens and then docker compose logs celery-worker --tail 30 to check the celery worker logs.

Applicable Issues

Closes #1580

@davinotdavid davinotdavid self-assigned this Apr 29, 2026
@davinotdavid davinotdavid force-pushed the enhancements/1580-auto-refresh-zoom-tokens branch from 9715027 to 91dbaec Compare April 29, 2026 21:51
@davinotdavid davinotdavid marked this pull request as ready for review May 1, 2026 18:01
Copy link
Copy Markdown
Member

@MelissaAutumn MelissaAutumn left a comment

Choose a reason for hiding this comment

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

Looks good, I have a few suggestions though. I can't test this locally right now, but I'm sure someone else can 😄

Comment thread backend/src/appointment/commands/refresh_zoom_tokens.py Outdated
Comment thread backend/src/appointment/routes/commands.py Outdated
@davinotdavid davinotdavid requested a review from MelissaAutumn May 1, 2026 20:11
Copy link
Copy Markdown
Member

@MelissaAutumn MelissaAutumn left a comment

Choose a reason for hiding this comment

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

Thanks for the change, just wanted to suggest a better flow for it though.

Comment thread backend/src/appointment/tasks/zoom.py Outdated
if lock_token is None:
log.info('Zoom token check is already running, skipping.')
return
else:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This logic should probably be wrapped in a context manager so we can just use

try:
    with task_lock('refresh_zoom_tokens'):
        run()
except TaskLockFailed:
    print('ah shoot it failed to acquire the lock')

... etc ...

With task_lock pulling redis instance, locking the task, and has a finally that unlocks the task. Default values can include the default lock ttl seconds.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah nice, indeed much better to do that! Changed, thanks!

Comment thread backend/src/appointment/tasks/locks.py Outdated
return 0
end
"""
redis_instance.eval(release_script, 1, lock_key, lock_token)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I hope this can be done without an eval 🤔

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmm I've replaced this with Redis' Transactions, what do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ohhh I should have seen this before commenting. That works for me!

@davinotdavid davinotdavid changed the title Auto-refresh zoom tokens via celery task Auto-refresh zoom tokens via celery task + implement task locks May 25, 2026
Copy link
Copy Markdown
Member

@MelissaAutumn MelissaAutumn left a comment

Choose a reason for hiding this comment

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

Just have some questions, no real changes. Looks good! Once they're answered I can approve.

Comment thread backend/src/appointment/tasks/locks.py

try:
yield
finally:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We might want to log all uncaught errors as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah yes, added an except there, thanks!

release_task_lock(redis_instance, task_name, lock_token)
except Exception as e:
logging.error(f'Failed to release {task_name} lock: {e}')
sentry_sdk.capture_exception(e)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I noticed sentry creates "issues" for logging.error as well as capture_exception. I'm not sure what would be the best solution here, maybe drop the log down to warning?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmmm I dropped the logging down to warning in this case and in the uncaught errors from the comment above too! Thanks!

@MelissaAutumn
Copy link
Copy Markdown
Member

I'm out today due to cat stuff, but will test tonight or tmw morning. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-refresh Zoom token access

3 participants