Skip to content

grpc 1.0 migration + Apache-2.0 license fix (v0.5.0)#9

Merged
nyo16 merged 3 commits into
masterfrom
feature/grpc-1.0-migration
Jun 26, 2026
Merged

grpc 1.0 migration + Apache-2.0 license fix (v0.5.0)#9
nyo16 merged 3 commits into
masterfrom
feature/grpc-1.0-migration

Conversation

@nyo16

@nyo16 nyo16 commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Summary

Migrates the pool to grpc ~> 1.0 (from 0.11.5) and reworks active
disconnect detection for grpc 1.0's new client-only connection model. Also
aligns the license declaration to Apache-2.0 (#6). Version bump to 0.4.0.

Why disconnect detection had to change

grpc 1.0's Gun adapter owns the socket inside its own supervised
ConnectionProcess. Empirically (spike):

  • On a drop, only the inner gun process dies — the ConnectionProcess
    (conn_pid in channel.adapter_payload) lingers as a zombie. So the
    plan's original idea of Process.monitor(conn_pid) can't detect drops.
  • grpc emits no connection-level telemetry (RPC spans only), so attaching
    to grpc telemetry doesn't work either.
  • The old :gun_down/:gun_error handlers in Worker were dead code — those
    messages now go to the adapter's process, never to us.

Fix: the worker monitors the inner gun process (read via
:sys.get_state(conn_pid).gun_pid, guarded, falling back to conn_pid) paired
with adapter_opts: [retry: 0], so gun fails fast on a drop and the pool's own
Backoff governs reconnection. GRPC.Stub.disconnect/1 reaps the zombie
ConnectionProcess on teardown.

This also restores fast-fail connects: a dead endpoint now errors in ~0ms
instead of stalling ~5s/attempt. The full test suite drops from ~364s to ~2.5s.

⚠️ Breaking change (telemetry)

The [:grpc_connection_pool, :channel, :gun_down] and :gun_error events are
removed (unreachable under grpc 1.0). A single adapter-agnostic
[:grpc_connection_pool, :channel, :connection_down] event (metadata
pool_name, reason) is emitted instead. :disconnected and
:reconnect_scheduled are unchanged. Consumers should switch to
:connection_down (or :disconnected).

Changes

  • deps: grpc ~> 1.0, gun ~> 2.2 (now a direct dep — grpc 1.0 makes it
    optional), cowboy ~> 2.14 (test); :public_key/:ssl in extra_applications.
  • worker: monitor the gun process, demonitor(ref, [:flush]) on disconnect,
    GRPC.Stub.disconnect/1 teardown; removed dead gun/mint message handlers.
  • config: adapter_opts: [retry: 0] (fast-fail + pool-governed reconnect).
  • tests: drive real drops via a Cowboy h2c server (test/support/)
    instead of synthetic gun messages; deleted obsolete disconnect_fix_test.exs;
    fixed a latent flaky test that hardcoded the live emulator port 8085.
  • license: mix.exs + README now declare Apache-2.0 to match the
    committed LICENSE file (fixes the Hex.pm mismatch).
  • docs: CHANGELOG 0.4.0, README install snippet + telemetry section.

Review notes

The one thing worth a close look: the worker reads gun_pid via
:sys.get_state/2 on grpc's adapter process — a deliberate, guarded coupling to
a grpc internal. It's the only way to detect drops under grpc 1.0 given the
zombie ConnectionProcess and the absence of connection telemetry; it falls
back to monitoring conn_pid if the internal state shape ever changes.

Verification

mix format --check-formatted ✓ · mix compile --warnings-as-errors ✓ ·
mix credo (no issues) ✓ · mix dialyzer (0 errors) ✓ ·
mix test → 75 passed, 3 excluded (emulator), ~2.5s ✓

Closes #6

nyo16 added 2 commits June 26, 2026 17:27
…nnect

Migrate to grpc ~> 1.0 (from 0.11.5) and rework active disconnect detection
for the new client-only connection model. Version 0.4.0.

grpc 1.0's Gun adapter owns the socket in its own ConnectionProcess, which
lingers as a zombie after a drop while only the inner gun process dies, and
grpc emits no connection-level telemetry. The worker now monitors the inner
gun process (read via :sys.get_state, guarded, falling back to conn_pid)
paired with adapter_opts: [retry: 0], so gun fails fast on a drop and the
pool's own Backoff governs reconnection. This also restores fast-fail
connects (a dead endpoint errors in ~0ms instead of stalling ~5s); the full
suite drops from ~364s to ~2.5s.

BREAKING (telemetry): the :gun_down and :gun_error channel events are removed
(unreachable under grpc 1.0). A single adapter-agnostic :connection_down event
is emitted instead; :disconnected and :reconnect_scheduled are unchanged.

- deps: grpc ~> 1.0, gun ~> 2.2 (now a direct dep), cowboy ~> 2.14 (test);
  :public_key/:ssl in extra_applications
- worker: monitor gun process, demonitor on disconnect, GRPC.Stub.disconnect
  reaps the zombie ConnectionProcess; remove dead gun/mint message handlers
- tests: drive REAL drops via a Cowboy h2c server (test/support) instead of
  synthetic gun messages; delete obsolete disconnect_fix_test.exs; fix a
  latent flaky test that hardcoded the live emulator port 8085
- docs: CHANGELOG 0.4.0, README install snippet + telemetry section
The committed LICENSE file is Apache-2.0, but mix.exs and the README declared
MIT, which propagated an incorrect license to the Hex.pm registry. Align the
declarations to Apache-2.0 to match the LICENSE file (issue #6, Option A).
@nyo16 nyo16 changed the title grpc 1.0 migration + Apache-2.0 license fix (v0.4.0) grpc 1.0 migration + Apache-2.0 license fix (v0.5.0) Jun 26, 2026
0.4.0 is already published, so this migration releases as 0.5.0. Split the
CHANGELOG so the grpc 1.0 migration + Apache-2.0 license fix sit under
[0.5.0] and the previously-shipped audit-remediation entries stay under
[0.4.0]; bump mix.exs and the README references accordingly.

Also fix a dialyzer guard_fail in test/support/grpc_test_server.ex: CI runs
`MIX_ENV=test mix dialyzer`, which analyzes test/support. `Process.sleep/1`
always returns :ok, so `Process.sleep(25) && do_wait_until(...)` had a dead
false-branch guard — replaced with sequential statements.
@nyo16 nyo16 merged commit 04304c2 into master Jun 26, 2026
6 checks passed
@nyo16 nyo16 deleted the feature/grpc-1.0-migration branch June 26, 2026 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

License declaration mismatch: LICENSE file is Apache-2.0 but mix.exs / README declare MIT

1 participant