Skip to content

v2.6.4

Choose a tag to compare

@vitobotta vitobotta released this 07 Jul 19:27
· 9 commits to main since this release
cec70cc

What's Fixed

Upstream connection drops are no longer misclassified as client disconnects. When a streaming request failed after chunks had already been forwarded to the client, try_stream caught errors from both sides of the proxy — upstream reads (response.read_body) and client writes (out << chunk) — in a single rescue block. Any IOError, EOFError, ECONNRESET, or Net::ReadTimeout from the upstream provider was converted to ClientDisconnected and logged as client_disconnect, making it appear as though the client had closed the connection when the upstream provider was actually the one that dropped.

Upstream errors that occur after partial stream are now wrapped in a new StreamPartiallySent exception and classified as upstream_disconnect in logs and metrics. Both client_disconnect and upstream_disconnect prevent retries (the client already has partial data), but only upstream_disconnect counts toward the circuit breaker — a client going away is not a provider failure.

Client disconnects no longer penalise providers or cascade through the fallback loop. Previously, when a client disconnected mid-stream, record_failure was called on the active provider, and the request continued to the next fallback provider — which would also fail to write to the dead client socket and also get record_failure. A single client disconnect could open circuits on every provider. with_auto_select now skips record_failure for client_disconnect and breaks out of both the provider loop and the rounds loop immediately.

Tests

  • 7 new tests: StreamPartiallySent does not retry and preserves the original error; ClientDisconnected does not retry; failure_reason returns upstream_disconnect for the new error; with_auto_select does not call record_failure for client disconnects; with_auto_select breaks the provider loop on client disconnect; with_auto_select breaks the rounds loop on client disconnect; with_auto_select still calls record_failure for upstream_disconnect. 1 existing test updated to assert the new StreamPartiallySent error string.
  • 129 runs, 301 assertions, 0 failures across 9 test files.