Documentation
¶
Overview ¶
Package cron is scheduled work that survives a restart: declare the schedule, then watch every run.
It is the platform's ONE cron system — durable schedules on the embedded hanzoai/tasks engine (cloud.EmbeddedTasks), replacing every k8s CronJob. There are no tickers here and no bespoke scheduler — the engine owns time (its 5s sweep fires due schedules; runs are durable workflows visible in the Tasks console at console.hanzo.ai/tasks and tasks.hanzo.ai).
Entries are DATA, not code: a ConfigMap in CRON_NAMESPACE labeled cron.hanzo.ai/enabled="true" declares one schedule —
data:
schedule: "30 1 * * *" # 5/6-field cron
job.yaml: | # EITHER: a batchv1 Job manifest to run
apiVersion: batch/v1
kind: Job
...
poke.json: | # OR: an HTTP poke
{"url":"http://pricing.hanzo.svc:8080/v1/sync",
"method":"POST","bearerEnv":"PRICING_API_KEY"}
so adding/changing/removing platform cron is a universe git edit — zero cloud code. A reconcile workflow (itself a durable schedule, cadence reconcileEvery) diffs ConfigMaps against registered schedules; the fire-time activity re-reads its ConfigMap fresh, so payload edits apply on the next tick without waiting for a reconcile.
Schedules live in the CRON_ORG org shard (default "hanzo") in namespace "default", so platform admins see and manage them in the org-scoped Tasks UI. Workers subscribe org-agnostically on (namespace, queue); the engine routes each run's state back to the owning shard via the task token's org.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Mount ¶
Mount registers the durable platform cron. The engine is wired after MountAll (durable.go), so the actual start happens in a bounded background wait; until then nothing is scheduled. Fail-soft: no engine or no k8s API leaves the subsystem idle (ConfigMap-less environments simply have zero entries), never blocks boot.
func ReconcileActivity ¶
ReconcileActivity is the scheduled half of reconcile (boot runs it inline).
func ReconcileWorkflow ¶
ReconcileWorkflow converges schedules onto the ConfigMap set (see reconcile in cron.go) as a single retried activity.
Types ¶
type EntryInput ¶
type EntryInput struct {
Name string `json:"name"`
}
EntryInput addresses one cron entry by ConfigMap name. It is the ONLY thing a schedule embeds — the activity resolves the current ConfigMap at fire time.
type JobResult ¶
type JobResult struct {
Job string `json:"job"`
}
PokeResult / JobResult surface run outcomes in the workflow result (what the Tasks console shows on the execution).
func JobWorkflow ¶
func JobWorkflow(ctx workflow.Context, in EntryInput) (JobResult, error)
JobWorkflow runs one k8s Job entry: a single UNretried activity (a failed backup Job must fail loudly in the console, not silently re-run; the next cron tick is the retry — the CronJob restartPolicy/backoffLimit inside the Job spec still governs pod-level retries).
func RunJobActivity ¶
func RunJobActivity(ctx context.Context, in EntryInput) (JobResult, error)
RunJobActivity resolves the entry's current job.yaml, enforces Forbid concurrency (an active run of the same entry skips this tick, matching the retired CronJobs' concurrencyPolicy), creates the Job, and blocks until it finishes. A failed Job fails the activity — and so the run in the console.
type PokeResult ¶
PokeResult / JobResult surface run outcomes in the workflow result (what the Tasks console shows on the execution).
func PokeActivity ¶
func PokeActivity(ctx context.Context, in EntryInput) (PokeResult, error)
PokeActivity resolves the entry's current poke.json and performs the HTTP call. Non-2xx is an error so the run fails visibly in the console.
func PokeWorkflow ¶
func PokeWorkflow(ctx workflow.Context, in EntryInput) (PokeResult, error)
PokeWorkflow runs one HTTP poke entry: a single retried activity. The endpoints behind pokes (billing sweep, pricing sync) are idempotent, so a couple of retries inside one tick are safe; across ticks the next fire is the retry.