GrpcConnectionPool.Worker (grpc_connection_pool v0.5.0)

Copy Markdown View Source

GenServer-based gRPC connection worker with automatic reconnection.

Each worker manages a single gRPC connection and stores its channel directly in the pool's ETS table for zero-GenServer-call access from Pool.get_channel/1.

Features:

  • Channels stored in ETS for O(1) pool access (no GenServer.call in hot path)
  • Automatic reconnection with exponential backoff and jitter
  • Active disconnect detection by monitoring the gRPC connection process
  • Self-registration in Registry for health tracking
  • Optional periodic ping to keep connections warm
  • Configurable max reconnect attempts before crash

Disconnect detection (grpc 1.0)

grpc 1.0's Gun adapter owns the socket inside its own supervised GRPC.Client.Adapters.Gun.ConnectionProcess, so gun's :gun_down/:gun_error messages no longer reach this worker. Worse, when the connection drops the inner gun process dies but the ConnectionProcess (the conn_pid in channel.adapter_payload) lingers as a zombie — so monitoring conn_pid cannot detect a drop.

Instead we monitor the inner gun process, read out of the adapter's ConnectionProcess state, and pair it with adapter_opts: [retry: 0] (see GrpcConnectionPool.Config) so gun gives up immediately on a drop and this pool's own Backoff governs reconnection. Reaching into the adapter state couples us to a grpc internal; it is guarded and falls back to monitoring conn_pid if the state shape changes.

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts a connection worker.

Gets the current connection status.

Functions

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()

Starts a connection worker.

Options:

  • :config — GrpcConnectionPool.Config struct (required)
  • :registry_name — Registry name for self-registration (required)
  • :pool_name — Pool name for telemetry (required)

status(worker)

@spec status(pid()) :: :connected | :disconnected

Gets the current connection status.