prefect server in zig

zig compatibility notes#

comparison of zig implementation with python prefect server.

RetryFailedFlows#

matching behavior ✓#

aspect python zig
from_states {RUNNING} StateTypeSet.init(&.{.RUNNING})
to_states {FAILED} StateTypeSet.init(&.{.FAILED})
retry check retries is None or run_count > retries ctx.retries orelse return; if (ctx.run_count > max_retries) return;
scheduled time now + timedelta(seconds=retry_delay or 0) now_us + delay_seconds * 1_000_000
retry state AwaitingRetry (SCHEDULED) SCHEDULED with name "AwaitingRetry"
response reject_transition(state, reason="Retrying") REJECT status

implemented ✓#

behavior status
retry_type = "in_process" on retry ✓ via set_retry_type_in_process flag
resuming = false on retry ✓ via set_resuming_false flag
pause_keys = [] on retry ✓ via clear_pause_keys flag
retry_type = null when exhausted ✓ via clear_retry_type flag

not needed#

  • old client compatibility (API < 0.8.3): python resets failed task runs to AwaitingRetry state - not needed for new clients

schema compatibility#

empirical_policy JSON#

python schema:

{
  "retries": int | null,
  "retry_delay": int | null,
  "pause_keys": [],
  "resuming": false,
  "retry_type": null | "in_process" | "reschedule",
  "max_retries": 0,        // deprecated
  "retry_delay_seconds": 0  // deprecated
}

zig reads: retries, retry_delay from this JSON zig stores: as TEXT (sqlite) or JSONB (postgres) - compatible

storage types#

column postgres python postgres zig sqlite python sqlite zig
id UUID UUID CHAR(36) CHAR(36)
timestamps TIMESTAMP(tz) TIMESTAMP(tz) DATETIME DATETIME
empirical_policy JSONB JSONB JSON TEXT

migration path#

our zig server stores data compatible with python prefect server:

  • UUIDs as standard format
  • timestamps as ISO 8601 UTC
  • JSON/JSONB for policy fields

data created by zig server can be read by python server (and vice versa).