SQLStreams

the messaging platform that is just Postgres

You last visited on 9999-99-99 Show what's new since then

0520 — Cron jobs are declared like every other resource; built-in alert config moves into RegisterSystem (amends 0518)

Edit this page
Posted: 2026-09-08 · Report this thread
brandon Site Admin brandon profile Posts: 677

Context. [0518] made code the only config writer, but left cron unresolved. Cron carries the same two-owner conflict as topic — RegisterCronJob asserts and raises ErrCronJobConfigMismatch, AlterCronJob mutates the same fields — and the repo had already worked around it a third way: ensureSystemCronJob creates the job only when missing, with the comment “RegisterCronJob is not used directly — its config-mismatch check would error on a job an operator has altered after creation”. Three mechanisms for one fact. Blocking the obvious sweep: the built-in alerts’ schedule and threshold are consts in vulkan’s own source (partitioncount/job.go const schedule = "@hourly", alert.NewJobData(0)), so cron alter is today the ONLY way a user can reach them, and alertlab asserts exactly that survival.

Decision.

  • Cron job fields (schedule, timeout, concurrency, data, metadata) are declaration. RegisterCronJob becomes latest-write-wins and ErrCronJobConfigMismatch is deleted outright — cron has no structural field like partition_size to keep it alive for. Name stays identity: a different name is a different job.
  • Each built-in alert grows its own JobConfig (Schedule, Threshold) in its package, with the current consts as its WithDefaults values. NewJob takes it.
  • admin.RegisterSystemConfig composes systemcontroller.SystemConfig with each alert’s JobConfig, and RegisterSystem takes it. The wrapper lives in pkg/admin because import arrows point downward — pkg/system sits below pkg/alert and cannot name it. SystemConfig stays the system domain’s own (still empty) knobs.
  • ensureSystemCronJob and ensureSystemTopic are deleted. Both exist only to dodge the mismatch check, so both collapse into ordinary register calls.
  • Register overwrites declared fields and never touches action state. Suspended is set by a verb, not declared, so a re-register leaves it alone. That is the line between config and action, and it holds everywhere.
  • A schedule change re-seeds the next scheduled time and drops a run already due under the old schedule. That was an explicit operator action and becomes a side effect of a deploy, so RegisterCronJob logs it at Info.

Consequences. cron_alter.go, AlertCronJob and AlertCronJobConfig join [0518]‘s deletion sweep; vulkan cron run, suspend and resume stay, being actions. Built-in alert thresholds and schedules become reachable from Go for the first time — today they are unreachable except through the CLI verb being deleted. RegisterSystem’s parameter type changes; call sites passing nil are unaffected. alertlab’s suspension assertion stands while its threshold assertion inverts: it proves an operator alter survives re-register today, and must prove a declaration applies instead. Rejected: hanging alert config off MessageAdminConfig, which avoids the signature change but files declared-into-the-database state beside instance-local concerns (logger, retry, AllowDestroy); and keeping cron alter as the one mutable resource, which would leave vulkan with two config models and no principle separating them.