Scheduled & background tasks
Long-running work uses Django's native task framework with a database
backend, picked up by the worker container (python manage.py db_worker).
Time-driven work (there is no built-in scheduler) runs through host cron.
Background tasks
Tasks are started on demand (for example from the admin panel) and executed by the worker. Every run produces a result row.
| Status | Meaning |
|---|---|
READY | Queued, waiting for a worker |
RUNNING | Currently being processed |
SUCCESSFUL | Completed without errors |
FAILED | Completed with an error |
Task results are shown read-only in the admin under Administration → System → Task status, scoped to the current institute.
Scheduled (cron) jobs
Cron runs on the host and calls Django management commands inside the server
container via docker compose exec.
| Cron name | Schedule | Command | Purpose |
|---|---|---|---|
| ses-cleanup-remote-seats | daily 03:00 | cleanup_remote_seats | Release expired remote-app seats |
| ses-prewarm-due-exams | every 5 min | prewarm_due_exams | Provision remote-app seats before exams |
| ses-import-ems-exams | every 5 min | import_ems_exams --scheduled | Import new/changed external exams |
| ses-cleanup-sso-sessions | daily 04:00 | ses_cleanup_sso_sessions | Remove expired SSO sessions |
| ses-cleanup-db-task-results | daily 04:05 | prune_db_task_results | Remove finished task results |
Example cron entry (SSO cleanup):
0 4 * * * cd /opt/ses && docker compose exec ses-server python manage.py ses_cleanup_sso_sessions --delete-orphan-users >> /var/log/ses-sso-cleanup.log 2>&1
Cleaning up task results
Finished results are pruned on a schedule to avoid database growth:
# Preview for 14-day-old successes, 45-day-old failures (no changes)
python manage.py prune_db_task_results --min-age-days 14 --failed-min-age-days 45 --dry-run
Django's task framework has a worker for the queue but no built-in scheduler, so time-based work is scheduled with host cron.
Removing expired SSO sessions
SSO sessions expire over time. To limit database growth and stay compliant with data retention, schedule a cleanup. The command iterates over all tenant schemas automatically.
# Preview what would be deleted (no changes)
python manage.py cleanup_expired_sso_sessions --dry-run
# Delete expired sessions (default: older than 30 days)
python manage.py cleanup_expired_sso_sessions
# Also remove orphaned user accounts
python manage.py cleanup_expired_sso_sessions --delete-orphan-users
| Option | Default | Purpose |
|---|---|---|
--dry-run | off | Show what would be deleted, change nothing |
--delete-orphan-users | off | Also remove users with no usable password and no sessions |
--max-age-days N | 30 | Only delete sessions older than N days |
Schedule it daily via cron:
0 3 * * * cd /opt/ses && docker compose exec ses-server python manage.py cleanup_expired_sso_sessions --delete-orphan-users >> /var/log/ses-sso-cleanup.log 2>&1
--delete-orphan-users only removes accounts with no usable password and
no remaining SSO sessions, so superusers and staff are never removed.