View Source ProcessHub.Service.Migration (ProcessHub v0.7.0)

Deferred-migration list and graceful node drain for the migration consent protocol. See ProcessHub.Strategy.Migration.MigrationConsent.

Summary

Functions

Parks children in the deferred list and ensures the retry tick runs.

Drains the local node before shutdown: removes it from the distribution cluster-wide, migrates every local child away through the consent gate, and force-migrates whatever is still deferred at the :timeout deadline (default 60000 ms). Leaves children untouched on error.

One retry pass: prunes entries whose child died or is assigned back to the local node, migrates the ready, re-consenting and expired ones, and returns the number of entries left.

Migrates one child to target_node, handing its state over per the hub's migration strategy — the same per-child move a drain performs, invocable for a single child with an explicit target. The child's declared-list entry is untouched by the move, so a crash mid-migration heals through the reconcile instead of losing the child.

Marks a deferred child ready; it migrates on the next retry tick.

Types

@type entry() :: %{
  child_id: ProcessHub.child_id(),
  deferred_at: integer(),
  ready: boolean()
}

Functions

Link to this function

defer_children(hub, child_ids)

View Source
@spec defer_children(ProcessHub.Hub.t(), [ProcessHub.child_id()]) :: :ok

Parks children in the deferred list and ensures the retry tick runs.

@spec deferred_child_ids(ProcessHub.Hub.t()) :: MapSet.t()
@spec deferred_list(ProcessHub.Hub.t()) :: [entry()]
Link to this function

drain(hub_or_id, opts \\ [])

View Source
@spec drain(
  ProcessHub.hub_id() | ProcessHub.Hub.t(),
  keyword()
) ::
  {:ok, %{migrated: non_neg_integer(), forced: non_neg_integer()}}
  | {:error, :no_target_nodes | :draining | :partitioned | :locked}

Drains the local node before shutdown: removes it from the distribution cluster-wide, migrates every local child away through the consent gate, and force-migrates whatever is still deferred at the :timeout deadline (default 60000 ms). Leaves children untouched on error.

@spec draining?(ProcessHub.Hub.t()) :: boolean()
@spec handle_retry_tick(ProcessHub.Hub.t()) :: non_neg_integer()

One retry pass: prunes entries whose child died or is assigned back to the local node, migrates the ready, re-consenting and expired ones, and returns the number of entries left.

Link to this function

migrate_child(hub_id, child_id, target_node)

View Source
@spec migrate_child(ProcessHub.hub_id(), ProcessHub.child_id(), node()) ::
  :ok | {:error, :not_found | :not_a_member | :same_node | term()}

Migrates one child to target_node, handing its state over per the hub's migration strategy — the same per-child move a drain performs, invocable for a single child with an explicit target. The child's declared-list entry is untouched by the move, so a crash mid-migration heals through the reconcile instead of losing the child.

Runs on the node currently hosting the child and routes itself there when called elsewhere. The consent protocol is NOT queried — the caller decides the child may move; a drain remains the consent-gated path.

The distribution strategy still considers the child assigned by its own arithmetic, so a later topology event may migrate it back — callers healing toward an off-assignment placement must be prepared to re-apply.

Link to this function

migration_ready(hub_id, child_id)

View Source
@spec migration_ready(ProcessHub.hub_id() | ProcessHub.Hub.t(), ProcessHub.child_id()) ::
  :ok | {:error, :not_deferred}

Marks a deferred child ready; it migrates on the next retry tick.

@spec retry_interval(ProcessHub.Hub.t()) :: pos_integer()