# `Shardex.Strategy`
[🔗](https://github.com/epinault/shardex/blob/v0.1.0/lib/shardex/strategy.ex#L1)

Behaviour for routing keys to shard names.

`route_many/2` is the only required callback: routing is batch-first and
single-key routing is derived from it unless `route/2` is implemented.

`ctx.shards` is the full configured shard list (in configuration order),
including shards in maintenance, so maintenance never remaps keys. Shardex
validates every result: unknown shard names become
`{:error, {:unknown_shard, name}}`, shards in maintenance become
`{:error, :maintenance}`, keys missing from the returned map become
`{:error, :unassigned}`.

A strategy may also be given as a function `(key, ctx -> result)`.

# `ctx`

```elixir
@type ctx() :: %{shards: [atom()], state: term(), instance: atom()}
```

# `result`

```elixir
@type result() :: {:ok, atom()} | {:error, term()}
```

# `init`
*optional* 

```elixir
@callback init(opts :: keyword(), shards :: [atom()]) :: {:ok, term()}
```

Builds the strategy state. Runs inside the Coordinator. Default: `{:ok, opts}`.

# `on_topology_change`
*optional* 

```elixir
@callback on_topology_change(state :: term(), shards :: [atom()]) :: {:ok, term()}
```

Called after `add_shard`/`remove_shard`. Default: `init(original_opts, shards)`.

# `route`
*optional* 

```elixir
@callback route(key :: term(), ctx()) :: result()
```

Routes one key. Default: `route_many([key], ctx)`.

# `route_many`

```elixir
@callback route_many(keys :: [term()], ctx()) :: %{optional(term()) =&gt; result()}
```

Routes many keys at once. Keys missing from the result are `:unassigned`.

# `trace?`
*optional* 

```elixir
@callback trace?() :: boolean()
```

Whether single-key routes emit `[:shardex, :route, ...]` spans. Default: `true`.

---

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