This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Workers

Periodic background jobs

Workers are periodic background jobs that run inside the xodbox process on a configurable schedule. They are the complement to Notifiers: notifiers react to inbound events in real time; workers run independently of traffic and operate on the captured data (pruning old records, aggregating stats, etc.).

Workers are registered in xodbox.yaml under a top-level workers: key, following the same key: value map convention used by handlers and notifiers.

Schedule expressions

The schedule key accepts any robfig/cron v3 expression:

ExpressionMeaning
@dailyOnce a day at midnight
@hourlyOnce an hour
@every 30mEvery 30 minutes
@every 6hEvery 6 hours
0 2 * * *Standard 5-field cron (daily at 02:00)
*/15 * * * *Every 15 minutes

Behaviour

  • If a worker is still running when its next tick fires, the new tick is silently skipped — there is no pileup.
  • A worker error is logged but does not stop the scheduler; the worker will run again on the next tick.
  • Workers are shut down gracefully: on SIGINT/SIGTERM xodbox cancels the context passed to Run and waits for any in-flight run to complete before exiting.

Example

workers:
  ## Docs: https://defektive.github.io/xodbox/docs/pkg/workers/purge/
  - worker: purge
    schedule: "@daily"
    max_age_days: "30"
    vacuum: "true"

Running a job manually

A worker does not have to wait for its next tick. There are two ways to run one on demand, and which you want depends on whether the server is running.

Admin console (server running)

The Jobs page lists every configured worker with its schedule, next fire time, and the outcome of its last run — how long it took, and any error. Press Run now to start one immediately.

The job runs inside the live xodbox process, so it shares the server’s database connection and will not fight it for SQLite’s write lock. This is the right choice while xodbox serve is up. The page is admin-only, since a job like purge deletes data permanently.

Under the hood:

EndpointMethodPurpose
/api/workersGETList workers and their last-run status.
/api/workers/{name}/runPOSTStart an out-of-schedule run.

The run endpoint replies 202 Accepted as soon as the run is accepted rather than waiting for it to finish — a purge that vacuums a large database can take minutes. Poll GET /api/workers for the outcome. It replies 404 for an unknown worker and 409 when a run is already in flight: a worker never overlaps with itself, whether the runs are scheduled or manual.

CLI (server stopped)

xodbox workers list          # what is configured, and on what schedule
xodbox workers run purge     # run it now, in the foreground

workers run waits for the job to finish and exits non-zero if it fails, which makes it usable from an external scheduler. Ctrl-C cancels the run’s context.

This opens its own connection to xodbox.db. If xodbox serve is running against the same file, a write-heavy job — the purge worker’s VACUUM in particular — can block or fail on SQLite’s write lock. Use the admin console instead, or stop the server first.

An empty workers list is the answer to “why did my background job never run?”: no workers: block means no job is ever scheduled.

Available workers

WorkerDescription
purgeDelete interactions older than N days

1 - Purge

Delete old interactions on a schedule

Deletes interaction records older than a configurable number of days, along with any files they captured, and reclaims the space on disk. Run this to keep the SQLite database from growing unbounded during long-running engagements.

Configuration

KeyRequiredDefaultNotes
workeryesMust be purge.
scheduleno@dailyCron expression or @every interval. See Workers.
max_age_daysno30Interactions older than this many days are deleted. Must be ≥ 1.
vacuumnotrueRun VACUUM after a purge that deleted rows, shrinking the database file.

Example

workers:
  # Delete interactions older than 14 days, every night at 02:00.
  - worker: purge
    schedule: "0 2 * * *"
    max_age_days: "14"
    vacuum: "true"

What gets deleted

Each run:

  1. Permanently deletes interactions older than max_age_days, together with their uploaded_files rows and BLOBs.
  2. Sweeps any rows left soft-deleted by an earlier version of xodbox or by the UI/API delete actions. These are invisible to every query but still occupy the database file.
  3. Runs VACUUM (unless vacuum: "false") to return the freed pages to the filesystem.

Deletes are permanent — there is no undo, and nothing in the UI can recover a purged interaction. Take a copy of xodbox.db first if the captured data matters to an engagement.

Notes

  • VACUUM rewrites the whole database. It needs temporary free disk space roughly equal to the current size of xodbox.db and holds a write lock for the duration, during which inbound interactions are not persisted. On a very large database, schedule it for a quiet hour. Set vacuum: "false" to skip it — deletes still free the pages for SQLite to reuse, the file just won’t shrink.
  • VACUUM is skipped when a run’s context is already cancelled (shutdown in progress) and when the run deleted nothing.
  • Deduplicated uploads are handled correctly: files are stored once per SHA-256 hash, and when the interaction holding the canonical copy is purged, the bytes are transferred to a surviving duplicate so its download keeps working.
  • max_age_days: "0" (or any non-positive or unparseable value) is silently ignored and the 30-day default is used instead.
  • Each run logs purge complete with the number of rows removed, and vacuum complete with bytes_reclaimed. If neither appears in the log, the worker is not configured — check for a workers: block in xodbox.yaml.
  • To apply the policy without waiting for the next tick, press Run now on the admin console’s Jobs page, or run xodbox workers run purge against a stopped server. See Running a job manually.