# `Runic.Runner.Worker`
[🔗](https://github.com/zblanco/runic/blob/main/lib/runic/runner/worker.ex#L1)

GenServer managing a single workflow's execution lifecycle.

The Worker implements the dispatch loop: plan → prepare → dispatch → apply,
using an `Executor` behaviour for fault-isolated task execution and
`PolicyDriver` for policy-aware invocation.

Workers are started under the Runner's DynamicSupervisor and registered
in the Runner's Registry for lookup by workflow ID.

## Executor

The executor controls _how_ runnables are dispatched to compute. By default,
`Runic.Runner.Executor.Task` is used (wrapping `Task.Supervisor.async_nolink`).
Pass `executor: MyExecutor` and `executor_opts: [...]` to use a custom executor.

The special value `executor: :inline` executes runnables synchronously in the
Worker process — useful for sub-millisecond computations where task spawn
overhead dominates.

## Per-Component Executor Overrides

When a `SchedulerPolicy` for a runnable includes an `:executor` field, the
Worker dispatches that runnable through the override executor instead of the
default. This allows mixing execution strategies within a single workflow.

## Scheduler

The scheduler controls _what_ gets dispatched together and _when_.
Pass `scheduler: MyScheduler` and `scheduler_opts: [...]` to use a
custom strategy. Built-in schedulers:

  - `Runic.Runner.Scheduler.Default` — dispatches each runnable individually (default)
  - `Runic.Runner.Scheduler.ChainBatching` — batches linear chains into Promises

The `promise_opts: [min_chain_length: N]` shorthand is equivalent to
`scheduler: Runic.Runner.Scheduler.ChainBatching, scheduler_opts: [min_chain_length: N]`.
An explicit `:scheduler` takes precedence over `:promise_opts`.

## Hooks

Lifecycle hooks allow observability and light customization without replacing
the Worker. Pass `hooks: [...]` in Worker opts:

  - `on_dispatch: fn runnable, worker_state -> :ok end`
  - `on_complete: fn runnable, duration_ms, worker_state -> :ok end`
  - `on_failed: fn runnable, reason, worker_state -> :ok end`
  - `on_idle: fn worker_state -> :ok end`
  - `transform_runnables: fn runnables, workflow -> runnables end`

Hook exceptions are logged but do not crash the Worker.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
