Port bandwidth leak prevention: backend degradation detection & gating#182
Port bandwidth leak prevention: backend degradation detection & gating#182full-bars wants to merge 1 commit into
Conversation
|
@xcolwell — requesting review on this bandwidth leak prevention PR. This ports the backend degradation detection and contract gating mechanisms from the fork I maintain to upstream, addressing issues #175 and #181. The implementation distinguishes sustained API outages from transient timeouts, then gates contract creation and applies exponential backoff when degraded. Validated in production during a recent 11-minute control API outage across ~120 servers—bandwidth consumption dropped to ~12% of baseline, confirming the mechanisms effectively reduce the leak. Related: PR#180 (log spam fixes for auth/contract/drop errors). |
|
Rewrote the degradation detection model. The previous implementation set a boolean flag when The new model uses a consecutive failure counter fed by both auth and OOB errors, reset immediately on any success. Trips after 3 consecutive failures within 2 minutes; clears the moment a single connect or OOB call succeeds. The gating and backoff behavior (contract creation, 30s retry interval, 64× RTT resend cap) is unchanged, only the signal feeding them is corrected. Also noticed a |
During a control-API outage providers keep creating contracts and resending against a dead backend, leaking metered bandwidth. This adds a process-wide degradation signal and uses it to throttle that waste. - consecutive-fail degradation model: isBackendDegraded() trips after backendDegradedFailThreshold (3) consecutive backend failures (auth or OOB) with the last failure within backendDegradedWindow (2m). Any success resets the counter; the recency window clears stale counts on idle providers. Failures/successes are recorded in the auth (H1/H3) and OOB-create paths. - gating in SendSequence.updateContract: stretch the contract retry interval to 30s and skip CreateContract entirely while degraded, so no new contracts are queued against an unreachable platform; recovery resumes within one retry interval once isBackendDegraded() clears. - self-contained rate-limit helpers (shouldLogAuthErr/shouldLogOobErr + package-level atomics) so this PR can merge independently of urnetwork#180. Logging routes through the per-instance self.log/self.client.log (upstream removed the global glog). The degraded-only resend backoff from the original branch is dropped: main already backs off resends multiplicatively (capped at MaxResendInterval), which subsumes it. Squashed from the original 2-commit branch so there is no intermediate state that depends on the removed glog.
6d2e486 to
acded84
Compare
Rebased onto current
|
Bandwidth Leak Prevention: Backend Degradation Detection & Gating
I've ported the proven backend degradation detection and contract gating mechanisms
from my v3.23-fix implementation
to upstream. This addresses the data leak during control API outages (issues #175, #181).
The Problem
When the control API is unreachable, providers continue attempting contract creation
and queueing transfers against a dead API. Without throttling, this becomes a massive
retry storm: thousands of route attempts per second, each spawning goroutines and
queuing transfers that will never complete because clients can't authorize.
The provider essentially screams at an API that isn't even listening, blasting the
network with data that has no chance of reaching a client. On metered bandwidth
connections (common for proxy providers), a sustained outage can consume an entire
month's bandwidth allocation in just a few hours. For proxy users relying on that
bandwidth, this translates to service loss beyond the API outage itself — the pipe
is wide open but the data is being wasted.
The core issue: there's no signal to the provider that the API is down. So it keeps
trying, keeps transferring, keeps wasting bandwidth, until either the outage ends or
the budget is exhausted. This fix adds that signal via degradation detection, then
uses it to stop the bleeding.
The Solution
Backend Degradation Detection:
positives from transient timeouts
Gating & Throttling When Degraded:
intervals instead of sending them in quick succession)
Production Validation
I validated this strategy during a recent control API outage on my fleet (2026-05-30, 3:10-3:21 PM PDT):
that the mechanisms effectively reduce (not eliminate) the leak
intended cleanup behavior (clients and contracts are long gone, so it amounts to
clearing queues). The strategy remains effective — the leak is contained during the
actual outage window.
Important caveat: An 11-minute window provides limited statistical power. The data
shows the mechanism works as designed, but edge cases or longer outages might reveal
new issues. The fix is based on production code that's been running in my
v3.23-fix implementation, so
confidence is high.
Implementation Details
transient timeouts
feedback loops
Related PRs