Migrating From v0.4 To v0.5

Copy Markdown View Source

v0.5 is the "production at scale" release. It adds cluster-aware wake routing, namespace-scoped run listing, search attributes, a structured query API, and mix continuum.audit.

Continuum is still pre-1.0. As with earlier 0.x releases, there is no production-data down-migration promise.

Database Migration

Generate and run the current migration:

mix continuum.gen.migration --repo MyApp.Repo
mix ecto.migrate

The v0.5 delta on top of v0.4 is:

  • continuum_runs.namespace text NOT NULL DEFAULT 'default'
  • continuum_runs.attributes jsonb NOT NULL DEFAULT '{}'
  • continuum_runs_attributes_gin_idx on continuum_runs USING gin (attributes)
  • continuum_runs_namespace_state_idx on (namespace, state)

Existing rows backfill through the column defaults. Fresh installs generated by mix continuum.gen.migration include these columns and indexes directly.

Cluster Requirement

Continuum now starts a :pg scope named :continuum. On a single BEAM this is just a local registry. In a distributed deployment it lets a node forward wakes to the node that currently owns a run process.

Continuum does not form the Erlang cluster for you. Use your application's existing distribution setup, such as libcluster, DNS, epmd, or release tooling. The lease and fencing token remain the authority for writes; :pg is advisory routing only.

Node death resume latency is the lease TTL, about 30 seconds by default. Faster node-liveness stealing is not part of v0.5.

New Public Surface

Start runs with namespace and search attributes:

{:ok, run_id} =
  Continuum.start(MyApp.Flow, input,
    namespace: "billing",
    attributes: %{customer_id: "cus_123", plan: "pro"}
  )

Query them later:

{:ok, page} =
  Continuum.query(
    namespace: "billing",
    where: [{:eq, [:attributes, "plan"], "pro"}],
    order_by: {:desc, :started_at}
  )

Continuum.get_run/2, Continuum.signal/4, Continuum.cancel/2, and Continuum.await/3 stay keyed by globally unique run_id; they do not require a namespace.

Continuum.set_attributes/3 merges JSON-encodable metadata into the run row. It does not append a journal event and workflow code cannot read it during replay.

Audit Task

mix continuum.audit --repo MyApp.Repo reports loaded workflow versions, stale Continuum.patched?/1 sites, and active runs whose workflow version is no longer loaded. Use --format json for automation and --strict to make CI fail on safe-to-remove patch sites or stuck unknown-version runs.

New Determinism Denylist Entries

Workflow code may no longer call:

  • :pg.*
  • :rpc.*
  • :erpc.*

These APIs depend on cluster topology and remote process state. Move that work into an activity. Run mix compile --warnings-as-errors after upgrading so any new scanner failures are visible before deployment.

Verification Checklist

Before deploying v0.5:

  • run mix format --check-formatted
  • run mix compile --warnings-as-errors
  • run mix test
  • run mix test.cluster if you use distributed Erlang
  • run CONTINUUM_PARANOID=1 mix test
  • run your usual seed sweep
  • dry-run mix continuum.audit --repo MyApp.Repo
  • verify dashboards and admin tools include the new namespace and attributes columns