Squidie.Runtime.ScheduleMetadata (squidie v0.1.2)

Copy Markdown View Source

Normalizes scheduler metadata for cron-triggered workflow starts.

Cron activation is intentionally host-owned: a host app decides when a declared cron trigger fires and queues a Squidie.Executor.Payload.cron/3 payload. This module translates that delivery payload plus the compiled workflow trigger definition into the durable context stored on the new run.

The persisted shape is reserved under run.context.schedule and is meant to answer two different questions:

  • what logical schedule window was intended by the scheduler
  • when Squidie actually received and started processing the signal
  • which stable idempotency key, when configured, protects the logical start

Keeping both timestamps matters because delayed delivery is normal in durable runtime systems. Workflow steps should not infer their schedule window from current wall-clock time; they should read the intended window from the run context.

The metadata is stored in run context rather than workflow payload so it does not participate in the workflow's business input contract. It also means the metadata survives reload, inspection, explanation, and replay without adding a database column for one trigger kind.

Summary

Functions

Builds the durable run context for one cron activation.

Types

t()

@type t() :: %{
  :workflow => String.t(),
  :trigger_name => String.t(),
  :cron_expression => String.t(),
  :timezone => String.t(),
  :received_at => String.t(),
  optional(:signal_id) => String.t(),
  optional(:idempotency) => :return_existing_run | :skip_duplicate,
  optional(:idempotency_key) => String.t(),
  optional(:intended_window) => map()
}

Functions

cron_context(workflow, map, payload)

@spec cron_context(module(), Squidie.Workflow.Definition.trigger(), map()) ::
  {:ok, %{schedule: t()}}
  | {:error, {:invalid_schedule_signal_id, term()}}
  | {:error, {:invalid_schedule_intended_window, term()}}
  | {:error, {:missing_schedule_idempotency_key, atom()}}

Builds the durable run context for one cron activation.

The workflow and trigger definition contribute stable declarative data such as the workflow name, trigger name, cron expression, and timezone. The payload contributes scheduler-delivery data such as signal_id and intended_window. If the scheduler omits signal_id, Squidie derives one from the workflow, trigger, and intended window when both window bounds are present. The runtime adds received_at at activation delivery time, so operators can compare scheduler intent against actual processing. Any received_at value in the payload is ignored because this timestamp belongs to the runner boundary.

When the cron trigger opts into idempotency, the runtime also stores idempotency and idempotency_key under the schedule context. The key is the scheduler signal_id, either supplied by the host scheduler or derived from a complete intended window. Without that identity, Squidie rejects the start because it cannot prove whether the activation is new or a duplicate.