All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.5.0] - 2026-06-26
Changed
- grpc 1.0 support. Bumped
grpcto~> 1.0(was0.11.5). grpc 1.0 is client-only (GRPC.Serverwas removed) and makes:gunoptional, sogun ~> 2.2is now a direct dependency (the pool uses the default Gun adapter).:public_keyand:sslare declared inextra_applications(used byConfig). - BREAKING (telemetry): the
[:grpc_connection_pool, :channel, :gun_down]and[:grpc_connection_pool, :channel, :gun_error]events were removed. Under grpc 1.0 the Gun adapter owns the socket in its own process, so those gun messages never reach the pool. A single adapter-agnostic[:grpc_connection_pool, :channel, :connection_down]event (metadatapool_name,reason) is emitted instead.:disconnectedand:reconnect_scheduledare unchanged. Consumers handling:gun_down/:gun_errorshould switch to:connection_down(or:disconnected). - Disconnect detection reworked. grpc 1.0's Gun adapter keeps the live
connection inside its own
ConnectionProcess, which lingers as a zombie after a drop, so the oldgun_down/gun_errormessage handlers were dead code. The worker now monitors the inner gun process and pairs it withadapter_opts: [retry: 0]so gun fails fast on a drop and the pool's ownBackoffgoverns reconnection. This also restores fast-fail connects (a dead endpoint now errors in ~0ms instead of stalling ~5s per attempt).
Fixed
- License declaration now correctly reports Apache-2.0 (matching the committed
LICENSEfile) instead of MIT inmix.exsand README — resolves the Hex.pm mismatch (#6).
[0.4.0] - 2026-06-01
Changed
- Security: production configs now default to verifying TLS.
Config.production/1setsverify: :verify_peer, and a:productionendpoint built withoutssl/credentialsno longer silently downgrades to plaintext h2c — it raises a clear configuration error. - Narrowed several broad
rescue/catchclauses (Pool.scale_up/scale_down,Worker.send_ping,TelemetryReporter) so unexpected errors surface instead of being swallowed; demoted expected reconnect/retry logs to:debug.
Fixed
- Documentation: replaced README examples referencing a non-existent
GrpcConnectionPool.execute/1with the realget_channel/1+ stub-call pattern; corrected the stale install snippet and the:get_channeltelemetry/strategy docs.
[0.3.5] - 2026-06-01
Fixed
- Slot-claim race in the hot path — slot claim/release are now serialized through
PoolState(register_channel/3,unregister_channel/2). Concurrent worker connects/disconnects could previously collide on a slot, leaving:channel_counthigher than the populated channels soget_channel/1returned:not_connectedon a healthy pool. get_channel/1now returns{:error, :not_connected}(instead of raising) when the pool is not started orPoolStateis restarting.
Changed
- Hot-path performance: collapsed the per-call ETS table-name rebuild + two
persistent_termlookups into one combined term;RoundRobinuses unsigned atomics (noabs/1);PowerOfTwonow tracks load in lock-free:atomicscounters (least-frequently-used) instead of writing a timestamp to ETS on every selection. - Per-call
:get_channeltelemetry is configurable viatelemetry_sample_rate(default1= emit every call;0disables;Nsamples ~1-in-N). - The
pid => slotmap moved from ETS intoPoolStatestate (slot claim is now O(1)).
[0.3.0] - 2026-03-24
Added
- Zero GenServer.call hot path — channels stored directly in ETS for O(1) indexed access, eliminating the GenServer.call bottleneck on every
get_channelrequest - Pluggable connection strategies via
GrpcConnectionPool.Strategybehaviour::round_robin(default) — lock-free atomics-based round-robin:random— random selection, good for avoiding hot-spotting:power_of_two— power-of-two-choices with least-recently-used tiebreak- Custom strategies supported via behaviour implementation
:persistent_termfor pool config — zero-copy reads for configuration data- ETS with read/write concurrency — optimized concurrent access flags
PoolStateGenServer — dedicated ETS table owner for crash resilienceTelemetryReporterGenServer — replaced recursive:timer.sleeptelemetry loop with a proper GenServer usingProcess.send_afterawait_ready/2— blocks until at least one channel is connected or timeout, useful for application startup- Stale scaling lock detection — scaling locks older than 30 seconds are automatically released
max_reconnect_attemptsconfig — workers crash after N consecutive connection failures instead of the fragilecrash_after_reconnect_attempttimer- Benchee benchmarks —
bench/get_channel_bench.exsfor measuring hot path performance - Strategy tests — comprehensive tests for all three built-in strategies
- CI/CD pipeline — GitHub Actions with compile, format, credo, test, dialyzer, and auto-publish to Hex on tag push
Changed
- 4.3x–5.8x faster
get_channel— single-process throughput improved from ~470K ips to ~2M ips - O(n) scaling eliminated — pool_size=25 was 38% slower than pool_size=5, now only 2% slower
- 44–58% lower latency under concurrency — 100 concurrent callers: median 553μs → 312μs, p99 1035μs → 439μs
- 28–56% less memory per call — memory now constant regardless of pool size (was O(n))
- Pool.status 2.5x faster — reads from ETS channel_count instead of Registry.lookup
- Pool supervision tree restructured: PoolState starts first, then Registry, DynamicSupervisor, workers, and TelemetryReporter
Removed
crash_after_reconnect_attemptmessage — replaced bymax_reconnect_attemptsconfig with clean{:stop, reason, state}on exhaustion
[0.2.3] - 2026-01-29
Added
- Enhanced telemetry events for better observability:
[:grpc_connection_pool, :pool, :init]- Pool initialization with size and endpoint[:grpc_connection_pool, :channel, :ping]- Ping health check with duration and result[:grpc_connection_pool, :channel, :gun_down]- Gun connection down events with reason and protocol[:grpc_connection_pool, :channel, :gun_error]- Gun error events with reason[:grpc_connection_pool, :channel, :reconnect_scheduled]- Reconnection scheduling with delay and attempt count
- Reconnect attempt tracking in worker state
- Comprehensive telemetry documentation in README
- Telemetry test suite
[0.2.2] - 2026-01-29
Added
- Support for gRPC client interceptors in endpoint configuration (thanks @arctarus)
- Comprehensive tests for interceptors feature
- CHANGELOG.md file
[0.2.1] - 2025-11-22
Fixed
- Handle GRPC v0.11.5 FunctionClauseError during disconnect
[0.2.0] - 2025-11-22
Added
- Dynamic pool scaling feature
[0.1.6] - 2025-11-22
Fixed
- Handle GenServer exit gracefully in connection cleanup
[0.1.5] - 2025-11-21
Changed
- Refactored to replace Poolex with DynamicSupervisor
- Added conn_grpc features
- Fixed documentation LICENSE reference warnings
[0.1.4] - 2025-11-19
Changed
- Updated dependencies: poolex to 1.4.2, grpc to 0.11.5
- Changed gRPC connection logs from info to debug level
Added
suppress_connection_errorsconfig option for GCP endpoints
[0.1.3] - 2025-11-18
Added
- License file
[0.1.2] - 2025-11-18
Added
- Comprehensive README with complete configuration examples and architecture details
[0.1.0] - 2025-11-18
Added
- Initial release: Complete GrpcConnectionPool library
- Configuration module with support for production, local, and custom environments
- Connection pooling with DynamicSupervisor
- Automatic connection warming and health monitoring
- Retry logic with exponential backoff and jitter
- Telemetry integration for metrics