feat: add management command to close stale ongoing conferences#9
Merged
Mupati merged 5 commits intoApr 1, 2026
Merged
Conversation
Adds cleanup_stale_conferences command that finds conferences with no event activity for longer than a threshold (default 4 hours) and closes them. Uses last GenericEvent timestamp, not conference creation time, so long-running active sessions are not affected. Usage: python manage.py cleanup_stale_conferences python manage.py cleanup_stale_conferences --hours 2 python manage.py cleanup_stale_conferences --dry-run
- Wrap each conference close in transaction.atomic() to match StopConferenceView and avoid partial updates - Isolate errors per conference with try/except so one bad row doesn't abort the rest - Use annotated query with Subquery to avoid N+1 queries - Add last_connection_at as fallback activity signal for conferences with no events - Read default hours from CONFERENCE_TIMEOUT_HOURS env var - Use consistent datetime.utcnow() throughout
Start a daemon thread in AppConfig.ready() that runs the cleanup periodically. No cron or external scheduler needed. Configurable via env vars: CONFERENCE_CLEANUP_INTERVAL_SECONDS (default: 3600) CONFERENCE_TIMEOUT_HOURS (default: 4) Set CONFERENCE_CLEANUP_INTERVAL_SECONDS=0 to disable.
- Add default_app_config in __init__.py so Django picks up the AppConfig - Use a module-level lock to ensure only one cleanup thread starts (gunicorn calls ready() multiple times for master + workers) - Remove debug print statements
The background thread in AppConfig.ready() only dedupes within one process (threading lock). With multiple gunicorn workers, each worker forks a separate process and runs its own cleanup loop. Gate the inline loop behind ENABLE_INLINE_CONFERENCE_CLEANUP=true so it's opt-in for dev/single-process. Production should use an external scheduler to run the management command. Also added cleanup documentation to README with dev vs production guidance.
Mupati
approved these changes
Apr 1, 2026
This was referenced Apr 15, 2026
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.
Summary
Add a Django management command to automatically close conferences stuck as "Ongoing" when there has been no event activity for a configurable threshold.
Problem
Conferences show as "Ongoing" indefinitely when the client fails to call
endCall()(browser tab closed, network drop, SDK not initialized). There is no server-side mechanism to clean these up.Solution
New management command
cleanup_stale_conferencesthat:ongoing=TrueGenericEventtimestamp for eachUses last event activity instead of conference creation time, so long-running active sessions (e.g., a 6-hour meeting still sending stats) are not affected.
Usage
Can be scheduled as a cron job to run hourly.
Test plan
--dry-run-- verify it shows the stale conference--dry-run-- verify conference is closed