# `Hermolaos.Pool`
[🔗](https://github.com/nyo16/hermolaos/blob/v0.5.0/lib/hermolaos/pool.ex#L1)

Connection pool for managing multiple MCP connections.

The Pool provides load balancing and fault tolerance for MCP operations
by maintaining multiple connections to one or more servers.

## Use Cases

1. **High throughput**: Distribute requests across multiple connections
2. **Redundancy**: Multiple connections to the same server for failover
3. **Multi-server**: Connect to multiple MCP servers simultaneously

## Architecture

The Pool uses a DynamicSupervisor to manage connections. Each connection
is a supervised `Hermolaos.Client.Connection` process. The pool uses a
Registry for efficient connection lookup.

## Example

    # Start a pool
    {:ok, pool} = Hermolaos.Pool.start_link(
      name: MyApp.MCPPool,
      connections: [
        [transport: :stdio, command: "server1"],
        [transport: :stdio, command: "server2"]
      ]
    )

    # Use checkout/checkin pattern
    {:ok, conn} = Hermolaos.Pool.checkout(MyApp.MCPPool)
    result = Hermolaos.call_tool(conn, "my_tool", %{})
    Hermolaos.Pool.checkin(MyApp.MCPPool, conn)

    # Or use transaction for automatic checkin
    result = Hermolaos.Pool.transaction(MyApp.MCPPool, fn conn ->
      Hermolaos.call_tool(conn, "my_tool", %{})
    end)

## Strategies

- `:round_robin` - Rotate through available connections (default)
- `:random` - Randomly select a connection
- `:least_busy` - Select connection with fewest pending requests

## Pool as Hermolaos Client

The pool itself implements the same interface as a single connection,
so you can use `Hermolaos.call_tool/4` etc. directly with the pool name.

# `pool`

```elixir
@type pool() :: Supervisor.supervisor()
```

# `pool_option`

```elixir
@type pool_option() ::
  {:name, atom()}
  | {:connections, [keyword()]}
  | {:size, pos_integer()}
  | {:strategy, strategy()}
  | {:connection_opts, keyword()}
```

# `strategy`

```elixir
@type strategy() :: :round_robin | :random | :least_busy
```

# `add_connection`

```elixir
@spec add_connection(
  pool(),
  keyword()
) :: {:ok, Hermolaos.Client.Connection.t()} | {:error, term()}
```

Adds a new connection to the pool.

## Examples

    {:ok, conn} = Hermolaos.Pool.add_connection(MyPool, transport: :stdio, command: "new-server")

# `checkin`

```elixir
@spec checkin(pool(), Hermolaos.Client.Connection.t()) :: :ok
```

Checks a connection back into the pool.

This is a no-op in the current implementation but is included for
API compatibility with checkout/checkin patterns.

# `checkout`

```elixir
@spec checkout(
  pool(),
  keyword()
) :: {:ok, Hermolaos.Client.Connection.t()} | {:error, :no_connections}
```

Checks out a connection from the pool.

Returns a connection that should be checked back in after use,
or used within a `transaction/2` block.

## Options

- `:timeout` - Maximum time to wait for a connection (default: 5000)

## Examples

    {:ok, conn} = Hermolaos.Pool.checkout(MyPool)
    # use conn...
    Hermolaos.Pool.checkin(MyPool, conn)

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `connections`

```elixir
@spec connections(pool()) :: [Hermolaos.Client.Connection.t()]
```

Returns the list of all connections in the pool.

# `handle_info`

# `remove_connection`

```elixir
@spec remove_connection(pool(), Hermolaos.Client.Connection.t()) ::
  :ok | {:error, :not_found}
```

Removes a connection from the pool.

# `start_link`

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

Starts a connection pool.

## Options

- `:name` - Pool name (required, used for registration)
- `:connections` - List of connection option keyword lists
- `:size` - Number of identical connections (alternative to `:connections`)
- `:connection_opts` - Common options for all connections when using `:size`
- `:strategy` - Load balancing strategy (default: `:round_robin`)

## Examples

    # Multiple connections with explicit configs
    {:ok, pool} = Hermolaos.Pool.start_link(
      name: MyPool,
      connections: [
        [transport: :stdio, command: "server1"],
        [transport: :http, url: "http://localhost:3000/mcp"]
      ]
    )

    # Pool of identical connections
    {:ok, pool} = Hermolaos.Pool.start_link(
      name: MyPool,
      size: 4,
      connection_opts: [transport: :stdio, command: "my-server"]
    )

# `stats`

```elixir
@spec stats(pool()) :: map()
```

Returns pool statistics.

# `transaction`

```elixir
@spec transaction(pool(), (Hermolaos.Client.Connection.t() -&gt; result)) :: result
when result: term()
```

Executes a function with a checked-out connection.

Automatically checks in the connection after the function completes.

## Examples

    result = Hermolaos.Pool.transaction(MyPool, fn conn ->
      Hermolaos.call_tool(conn, "my_tool", %{arg: "value"})
    end)

---

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