Arcadic.Transport.Grpc.ChannelPool (Arcadic v1.0.0)

Copy Markdown View Source

Caller-supervised shared-channel cache for Arcadic.Transport.Grpc.

A gRPC channel is HTTP/2-multiplexed — many concurrent streams share ONE connection — so this is a shared channel cache (one long-lived channel per {host, port, tls?, trust-selection} endpoint reused across ALL calls with the SAME trust config), NOT an exclusive checkout pool that would serialize streams. It opt-in: add

children = [{Arcadic.Transport.Grpc.ChannelPool, []}]

to your supervision tree. When it is running, the transport reuses its channel; when it is absent, the transport falls back to a fresh per-call connect (no behavior change). Tenant-blind — keyed on the endpoint + trust selection only, carrying no database/scope. Rationale for the process: a live gRPC channel is a socket/connection process (adapter_payload.conn_pid), not an immutable value copied into a pure-data Conn — sharing one requires a process, which is why the pool is opt-in and caller-supervised rather than transport-internal.

The cache serializes checkout through the GenServer so two concurrent first-connects don't race into two channels; a dead channel (its adapter connection process gone) is transparently reconnected.

Summary

Functions

Return a healthy channel for key, connecting via connect_fn (a 0-arity -> {:ok, channel} | {:error, term}) and caching it if the endpoint has no live channel yet.

Returns a specification to start this module under a supervisor.

Functions

checkout(key, connect_fn)

@spec checkout(term(), (-> {:ok, term()} | {:error, term()})) ::
  {:ok, term()} | {:error, term()}

Return a healthy channel for key, connecting via connect_fn (a 0-arity -> {:ok, channel} | {:error, term}) and caching it if the endpoint has no live channel yet.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()