EXECUTION.md
Scope
This document defines how Kron executes scheduled work in non-Kubernetes mode (krond). It describes:
Daemon lifecycle
Job process model
Forking and execution
Concurrency handling
State management
Failure handling
This specification applies to krond.
Kubernetes execution is delegated to native Job resources and is not defined here.
Process Model Overview
Kron consists of:
krond— long-running daemonkrontab— configuration manager (writes config files)Child processes — spawned per scheduled execution
krond is the only persistent process.
Each scheduled execution results in exactly one fork/exec cycle.
krond Lifecycle
Startup
On startup, krond:
Loads configuration files.
Validates all schedule syntax.
Loads persisted state from disk.
Computes the next period and chosen execution time for each entry.
Starts the scheduler loop.
Optionally writes PID file.
If configuration is invalid, krond exits with non-zero status.
Scheduler Loop
krond maintains an in-memory priority queue ordered by next chosen execution time.
Main loop:
Determine earliest scheduled execution.
Sleep until that timestamp.
Wake up.
Recompute decision for that job to confirm it is still valid.
Attempt execution.
Compute next period and chosen time.
Reinsert into queue.
Time is always compared in UTC internally.
If system clock jumps forward, missed-period logic is applied. If system clock jumps backward, the queue is recalculated.
Job Identity
Each schedule entry has a stable identity:
<config_path>:<name>
Where <config_path> is the absolute path to the configuration file and <name> is the name field defined in the entry. See KRONTAB.md for the file format specification.
This identity is used for:
Seed derivation
Locking
State files
Logging
Fork and Exec Model
When a job is triggered:
krondcallsfork().Child process calls
execve()with configured command.Parent process:
Records child PID
Monitors exit status via
waitpid()
No shell wrapping is performed unless explicitly configured.
Default behavior:
Command is executed directly.
Arguments are passed as defined.
Environment is inherited from
krondunless overridden.
Execution Environment
Each job may define:
usergroupenvcwdumasktimeout
Before execve():
If running as root and
userspecified:setgid()setuid()
Apply
chdir()ifcwddefined.Apply
umask()if defined.Set environment variables.
If privilege drop fails, execution is aborted.
Concurrency Handling
Each job has a concurrency policy:
allowforbidreplace
allow
Multiple child processes may run simultaneously.
forbid
If a previous child process is still active:
New execution is skipped.
Event is logged.
Period is marked as skipped.
replace
If a previous child process is active:
Send
SIGTERMto active PID.Wait configurable grace period.
If still running, send
SIGKILL.Start new process.
Timeout Handling
If timeout is defined:
Parent tracks execution duration.
When timeout expires:
Send
SIGTERM.Wait grace period.
Send
SIGKILLif necessary.
Log timeout event.
Timeout applies per execution instance.
State Persistence
State is stored in:
/var/lib/krond/<hash>.json
State file contains:
Last handled period identifier
Last chosen execution time
Last run time
Last exit code
Active PID (if any)
Concurrency state
Seed metadata
State is written:
After scheduling decision
After execution completes
After skip due to concurrency
After missed deadline
Writes are atomic:
Write to temporary file.
fsync().
Rename.
Missed Period Handling
If krond is down during a chosen execution time:
On restart:
Compute period for current time.
Determine whether chosen time is in the past.
Apply deadline policy.
If deadline is zero:
Missed periods are skipped.
Only future periods are scheduled.
If deadline is non-zero:
If now <= chosen + deadline:
Execute immediately.
Otherwise:
Skip period.
No historical backlog is ever replayed beyond one bounded period.
Output Handling
Child process STDOUT and STDERR are handled by:
Inherit mode (default)
Redirect to file
Redirect to syslog
Discard
If redirected to file:
File path may include time formatting tokens.
Files are opened before fork.
Parent ensures file descriptors are closed.
Exit codes are logged.
Signal Handling
krond handles:
SIGTERMSIGINTSIGHUP
SIGTERM / SIGINT
Stop accepting new triggers.
Allow active child processes to complete.
Optionally terminate active processes if configured.
Persist state.
Exit cleanly.
SIGHUP
Reload configuration.
Validate new schedules.
Recompute queue.
Preserve active child processes.
Invalid new configuration does not replace old configuration.
Locking Model
krond enforces single-daemon per system using:
PID file with file lock.
Or advisory lock on state directory.
If lock acquisition fails, daemon exits.
Isolation and Security
No command is executed through shell by default.
No interpolation is performed unless explicitly configured.
Environment variables must be explicitly defined to override inherited values.
Privilege drop is required for user switching.
Resource Limits
krond may configure:
RLIMIT_NOFILERLIMIT_NPROCOptional per-job limits if supported
System resource limits are not modified unless explicitly configured.
Crash Recovery
If krond crashes:
State files remain intact.
On restart:
Active PID in state is verified.
If PID exists and matches expected command, it is considered active.
If PID does not exist, state is corrected.
No duplicate execution occurs for the same period.
Determinism Guarantee
For each job and period:
The chosen execution time is stable across daemon restarts.
Seed derivation is stable.
Fork timing may vary slightly due to scheduler latency, but chosen timestamp is invariant.
Performance Model
krond must support:
Thousands of schedule entries.
Sub-second scheduling precision.
O(log n) insertion/removal from scheduling queue.
Minimal CPU usage when idle.
Memory usage scales linearly with number of entries.
Failure Guarantees
Kron guarantees:
At most one execution per period.
No uncontrolled backfill.
No duplicate execution due to restart.
No hidden implicit retries.
Execution failures are surfaced through logs and exit codes only.
Kron does not retry failed commands unless explicitly configured in future versions.
Summary
krond is:
A single-process scheduler.
Deterministic in decision-making.
Fork/exec based.
Policy-driven in concurrency.
Bounded in catch-up behavior.
Transparent in logging.
Safe by default.