Task Scheduler
OpenTremor Core has no scheduler of its own — no periodic loop, no cron. OpenTremor-task-scheduler
is a small standalone process that fills that gap by calling core’s admin HTTP endpoints on an
interval, the same “talks to core at runtime, not the code level” relationship the dashboard and
docs site have. See Data Retention,
Platform Admin — Deleting an organization, and
Platform Admin — Retrying a failed job for the three
features this currently drives.
What it does
Section titled “What it does”Reads a jobs: list from its own config file — {name, method, path, heartbeat_minutes} — and
calls {core.base_url}{path} on that interval, forever. The three jobs shipped today:
jobs: - name: retention_sweep method: POST path: /admin/retention/run heartbeat_minutes: 15 - name: org_purge method: POST path: /admin/organizations/purge-pending heartbeat_minutes: 60 - name: jobs_sweep method: POST path: /admin/jobs/sweep heartbeat_minutes: 15heartbeat_minutes is deliberately short and dumb for all three. The real schedule
(retention.sweep_interval_hours / org_offboarding.grace_period_days / jobs.sweep_interval_hours,
all admin-configurable on core itself) lives on core, which either self-gates (retention and
jobs_sweep: a call before the interval has elapsed returns the previous result with
skipped: true) or naturally no-ops (org purge: nothing to do until an org is actually past its
grace period) instead of doing real work on every tick. The scheduler doesn’t know or care what
“retention”, “org offboarding”, or “stuck job” mean — it just needs to ping often enough that a
due action gets picked up promptly. More jobs are config additions here, not new scheduler code.
Credential
Section titled “Credential”Authenticates with core’s bootstrap auth.api_key, not a per-service API key created via
POST /auth/keys — a regular service account is always scoped to one org with an OrgRole
(owner/admin/member/viewer) and can never be is_superadmin, which POST /admin/retention/run
requires. The bootstrap key is the one credential in core that’s both usable with no database
round-trip and always superadmin, by design (see configuration/reference/#auth) — reusing it
here is the same bootstrap-independence reasoning that credential already exists for, not a new
exception carved out for this repo.
Set OPENTREMOR_SCHEDULER_API_KEY to the target core instance’s auth.api_key — treat it with
the same care as core’s own config (a secret store or Kubernetes Secret in production, never a
plaintext value committed anywhere).
Running it
Section titled “Running it”poetry installCONFIG_FILE=configs/opentremor-task-scheduler.yaml \ OPENTREMOR_SCHEDULER_API_KEY=<core's auth.api_key> \ poetry run python src/server.pyOr via the workspace’s docker-compose.dev.yaml / docker-compose.prod.yaml, which already
wire a task-scheduler service pointed at opentremor-core:8000.
Observability
Section titled “Observability”GET /healthz— process liveness (used by the containerHEALTHCHECK).GET /jobs— last tick per configured job: timestamp, ok/error, HTTP status, a short response summary. This is only “did the heartbeat itself succeed” — core’s ownGET /admin/retention/statusis the durable record of what a sweep actually did.