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.
[Unreleased]
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