# `Slap.Cluster.Host`
[🔗](https://github.com/mjrusso/slap/blob/slap_cluster-v0.4.0/slap_cluster/lib/slap/cluster/host.ex#L1)

Starts and stops the shards placed on this node, for the strategy.

Opens and closes run in tasks, so several run at once. If one of these
tasks fails, the host stops: the shard may or may not be running, and
the cluster's supervisor then stops every shard and starts over.

Each shard runs under its own supervisor: the process that owns the
database, then the application's shard children. The host watches them
and reports every shard that stops to the strategy's
`c:Slap.Cluster.Strategy.handle_shard_down/3`: `:fenced`, `:crashed` or
`:stopped`. It never restarts a shard by itself; that is the strategy's
decision.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `local_shards`

```elixir
@spec local_shards(module()) :: [non_neg_integer()]
```

The shards running on this node.

# `send_start`

```elixir
@spec send_start(
  module(),
  non_neg_integer(),
  keyword(),
  term(),
  :gen_server.request_id_collection()
) ::
  :gen_server.request_id_collection()
```

`start_shard/3` and `stop_shard/2` without waiting: the request is sent
from the calling process and added to `requests` (a `:gen_server`
request id collection) under `label`; its reply is a message, for
`:gen_server.check_response/3`. The host handles the requests of one
process in the order they were sent, so a stop sent after a start is
handled after it.

# `send_stop`

```elixir
@spec send_stop(
  module(),
  non_neg_integer(),
  term(),
  :gen_server.request_id_collection()
) ::
  :gen_server.request_id_collection()
```

See `send_start/5`.

# `start_shard`

```elixir
@spec start_shard(module(), non_neg_integer(), keyword()) ::
  {:ok, pid()} | {:error, term()}
```

Opens shard `n` on this node and starts its children. Options:
`:generation`, the strategy's lease generation (default `nil`).

Returns `{:ok, pid}`, `{:error, :already_started}`, `{:error, :stopping}`
(it is still closing), `{:error, :fenced}` (another node opened it while
it was opening here), `{:error, :stopped}` (`stop_shard/2` was called
while it was opening; it is closed, and was never `:running` since) or `{:error, reason}` (for example
when the database cannot be opened). Opens run concurrently.

# `stop_shard`

```elixir
@spec stop_shard(module(), non_neg_integer()) :: :ok | {:error, :not_running}
```

Stops shard `n` on this node: its children first, then the database is
closed, which flushes it. A shard that is still opening counts as
stopping at once (`Slap.Cluster.lookup/2` no longer finds it here), and
is closed once it has opened. Returns `:ok` or `{:error, :not_running}`. Stops run
concurrently.

---

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