code wiki / (root) / nx_cron.nx

nx_cron.nx

buildroot/runtime/nx_cron.nx

21844 B465 linesdepth 2pulls 3 transitivereach 4 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_cron.nx -- JOB-REGISTRY + DISPATCH-LOOP layer above the FULLY_WIRED nx_race_timing.nx primitive (sealed 8-mode timing taxonomy). Replaces /etc/crontab on Synology DSM. AUDIT-FIRST CORRECTION (2026-05-20, post-creation): user caught that I built this without checking for existing prior art. nx_race_timing.nx already ships the canonical sealed enum of 8 timing modes (MANUAL / EVENT / SCHEDULED / CONTINUOUS / IDLE / THRESHOLD / PROBABILISTIC / QUORUM) + the classifier helpers (is_reactive / needs_config / parse). My nx_cron 9-kind enum maps directly: NX_CRON_KIND_INTERVAL_SECONDS/MINUTES/HOURS -> NX_RACE_TIMING_CONTINUOUS NX_CRON_KIND_DAILY_AT_HOUR/WEEKLY_AT_DOW/MONTHLY_AT_DOM -> NX_RACE_TIMING_SCHEDULED NX_CRON_KIND_ON_EVENT -> NX_RACE_TIMING_EVENT NX_CRON_KIND_ON_DEMAND -> NX_RACE_TIMING_MANUAL NX_CRON_KIND_IDLE_OPPORTUNISTIC -> NX_RACE_TIMING_IDLE nx_cron does NOT replace nx_race_timing -- it COMPOSES against it. nx_race_timing classifies a timing mode; nx_cron registers + dispatches JOBS attached to those timing modes. Different layer: - nx_race_timing : WHAT timing mode is this? (taxonomy + classifier) - nx_cron : HOW do we run job X on schedule Y? (registry + loop) When graduated, nx_cron_register_job will call into nx_race_timing helpers (nx_race_timing_is_valid, nx_race_timing_needs_config) to validate the declared schedule before persisting the job. Also composes with the already-shipped nx_timerfd.nx for the actual fire-time wakeup. Per feedback-no-temporary-third-party-scaffolding-when-substrate-arc-exists audit-first rule: ls nxc2/runtime/ before authoring new primitives. module: nishi-core.ops.cron depends: nishi-core.race.timing + nishi-core.io.syscalls disk_kb: 5 capability: OPS wired_status: PARTIAL_WIRED WIRED (2026-06-13, W-RE-CRON-001 -- the in-memory DISPATCH CORE, gate-proven by nx_cms_schedule_gate -> a real schedule->publish): - JOB_REGISTRY (static in-memory job table; register/unregister/find

dependencies 2 imports · 3 importers

nx_syscalls.nx nx_race_timing.nx nx_cron.nx nx_cms_booking.nx nx_cms_schedule_exceed_gate.nx nx_cms_schedule_gate.nx

imports: nx_syscalls.nxnx_race_timing.nx

imported by: nx_cms_booking.nxnx_cms_schedule_exceed_gate.nxnx_cms_schedule_gate.nx

structs

161struct NxCronJob

consts

96const NX_CRON_KIND_INTERVAL_SECONDS: i64 = 1 // every N seconds (CONTINUOUS)
97const NX_CRON_KIND_INTERVAL_MINUTES: i64 = 2
98const NX_CRON_KIND_INTERVAL_HOURS: i64 = 3
99const NX_CRON_KIND_DAILY_AT_HOUR: i64 = 4 // SCHEDULED at HH:MM
100const NX_CRON_KIND_WEEKLY_AT_DOW: i64 = 5 // SCHEDULED day-of-week
101const NX_CRON_KIND_MONTHLY_AT_DOM: i64 = 6
102const NX_CRON_KIND_ON_EVENT: i64 = 7 // EVENT-driven; not periodic
103const NX_CRON_KIND_ON_DEMAND: i64 = 8 // MANUAL; explicit trigger only
104const NX_CRON_KIND_IDLE_OPPORTUNISTIC: i64 = 9 // IDLE; substrate runs when
106const NX_CRON_KIND_AT_UNIX_ONCE: i64 = 10 // SCHEDULED one-shot at absolute
125const NX_CRON_MISSED_SKIP: i64 = 1 // missed fires forgotten
126const NX_CRON_MISSED_CATCH_UP_ONCE: i64 = 2 // fire ONCE if any missed
127const NX_CRON_MISSED_CATCH_UP_ALL: i64 = 3 // fire every missed (rare;
132const NX_CRON_VERDICT_OK: i64 = 0
133const NX_CRON_VERDICT_JOB_REGISTERED: i64 = 1
134const NX_CRON_VERDICT_JOB_UPDATED: i64 = 2
135const NX_CRON_VERDICT_JOB_UNREGISTERED: i64 = 3
136const NX_CRON_VERDICT_JOB_FIRED: i64 = 4
137const NX_CRON_VERDICT_JOB_FAILED: i64 = 5
138const NX_CRON_VERDICT_FAIL_BAD_SCHEDULE: i64 = 6
139const NX_CRON_VERDICT_FAIL_DUPLICATE_NAME: i64 = 7
140const NX_CRON_VERDICT_FAIL_SUPERVISOR_MISSING: i64 = 8
141const NX_CRON_VERDICT_FAIL_DEPENDENCY_MISSING: i64 = 9 // PARTIAL_WIRED default
186const NX_CRON_ACTION_NONE: i64 = 0
187const NX_CRON_ACTION_PUBLISH: i64 = 1
197const NX_CRON_MAX_JOBS: i64 = 64
198const NX_CRON_REC_BYTES: i64 = 128 // 16 i64 slots per job
199const NX_CRON_TABLE_BYTES: i64 = 8192 // 64 * 128
200const NX_CRON_FIRED_CAP: i64 = 64
203const CJ_IN_USE: i64 = 0
204const CJ_NAME_HASH: i64 = 1
205const CJ_NAME_LEN: i64 = 2
206const CJ_KIND: i64 = 3
207const CJ_INTERVAL: i64 = 4
208const CJ_FIRE_AT: i64 = 5 // absolute next-fire unix seconds
209const CJ_MISSED: i64 = 6
210const CJ_ACTION_K: i64 = 7
211const CJ_ACTION_A: i64 = 8
212const CJ_ENABLED: i64 = 9
213const CJ_FIRED_CNT: i64 = 10
214const CJ_LAST_FIRE: i64 = 11
215const CJ_RECURRING: i64 = 12

functions

109func nx_cron_kind_name(k: i64) -> *u8
143func nx_cron_verdict_name(v: i64) -> *u8
224func nx_cron_init() -> i64
244func nx_cron_kind_race_mode(k: i64) -> i64
called by 1: nx_cron_schedule_ok
260func nx_cron_schedule_ok(job_ptr: *NxCronJob) -> i64
270func nx_cron_recurring(k: i64) -> i64
282func nx_cron_name_hash(p: *u8, n: i64) -> i64
290func nx_cron_rec(slot: i64) -> *i64
295func nx_cron_find(nh: i64, nl: i64) -> i64
306func nx_cron_fired_push(kind: i64, arg: i64) -> i64
316func nx_cron_drain_fired(out_kind: *i64, out_arg: *i64) -> i64
called by 2: se_tickmain calls 1: nx_cron_init
329func nx_cron_fire_slot(rec: *i64, now: i64) -> i64
called by 1: nx_cron_tick calls 1: nx_cron_fired_push
346func nx_cron_register_job(job_ptr: *NxCronJob) -> i64
385func nx_cron_unregister_job(job_name_ptr: *u8, job_name_len: i64) -> i64
400func nx_cron_fire_now(job_name_ptr: *u8, job_name_len: i64) -> i64
416func nx_cron_tick(current_unix_seconds: i64) -> i64
438func nx_cron_count_jobs() -> i64
called by 2: mainmain calls 2: nx_cron_initnx_cron_rec
452func nx_cron_job_fired_count(job_name_ptr: *u8, job_name_len: i64) -> i64
462func nx_cron_get_last_verdict() -> i64
calls 1: nx_cron_init