Skip to content

review: outage bandwidth leak staging mirror - #3

Merged
full-bars merged 2 commits into
mainfrom
upstream/outage-bandwidth-leak
Aug 6, 2026
Merged

review: outage bandwidth leak staging mirror#3
full-bars merged 2 commits into
mainfrom
upstream/outage-bandwidth-leak

Conversation

@full-bars

@full-bars full-bars commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Staging mirror for CodeRabbit review. Do not merge.

1 commit, 7 files, +668/-17.

Validation on this commit: go build, go vet, gofmt clean; 17 tests green under -race; full package test suite green at 477s.

Summary by CodeRabbit

  • Reliability

    • Improved resilience during backend degradation by pausing contract acquisition and retrying at safer intervals.
    • Retry intervals increase gradually, avoid overshooting configured limits, and resume normal behavior after recovery.
    • Contract acquisition automatically resumes once backend connectivity is restored.
    • Authentication and connection handling recover more cleanly from transient failures.
  • Logging

    • Repeated route-drop, contract, authentication, and connection errors are throttled to reduce log noise.
    • Suppressed events are summarized when logging resumes, preserving visibility into recurring issues.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c43c330f-2c30-4b50-9b44-c88d0cad240a

📥 Commits

Reviewing files that changed from the base of the PR and between 9dc9531 and ed80fde.

📒 Files selected for processing (10)
  • backend_degraded_contract_manager_test.go
  • backend_degraded_gate_test.go
  • backend_degraded_test.go
  • log_throttle.go
  • log_throttle_fallback_test.go
  • log_throttle_package_vars_test.go
  • log_throttle_test.go
  • transfer.go
  • transfer_contract_manager.go
  • transport.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • log_throttle.go
  • backend_degraded_gate_test.go
  • transfer.go
  • transfer_contract_manager.go
  • backend_degraded_test.go
  • transport.go

📝 Walkthrough

Walkthrough

The PR adds process-wide backend degradation tracking, lock-free log throttling, degraded-mode contract request gating, maximum-interval retry initialization, and throttled transport and transfer error logging. Tests cover thresholds, recovery, concurrency, retry convergence, and suppression counts.

Changes

Backend degradation controls

Layer / File(s) Summary
Degradation state and throttled logging
log_throttle.go, log_throttle_test.go, log_throttle_fallback_test.go, log_throttle_package_vars_test.go, transport.go, backend_degraded_test.go
Transport paths record backend failures and successes. Degradation uses a three-failure threshold within a two-minute window. The atomic throttle counts suppressed calls. Tests cover state transitions, concurrency, fallback logging, wiring, and reset behavior.
Transport authentication and write-error handling
transport.go
WebSocket and QUIC authentication failures update shared degradation state unless local cancellation caused the failure. Successful authentication clears the state. Authentication and write errors use throttled informational logging with verbose fallback.
Degraded contract acquisition and retry
transfer.go, transfer_contract_manager.go, backend_degraded_gate_test.go, backend_degraded_contract_manager_test.go
Contract creation is skipped during degradation, retries start at the maximum interval, and acquisition resumes after recovery. Route-drop and out-of-band contract errors use throttled logging. Tests cover gating, retry backoff, saturation, recovery, and shutdown handling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Transport
  participant BackendDegradation
  participant Transfer
  participant ContractRetryLoop
  participant Backend
  Transport->>Backend: authenticate or write
  Backend-->>Transport: success or error
  Transport->>BackendDegradation: record success or failure
  Transfer->>BackendDegradation: check degraded state
  BackendDegradation-->>Transfer: return degradation status
  Transfer->>ContractRetryLoop: skip or schedule contract creation
  ContractRetryLoop->>Backend: retry after configured interval
Loading

Possibly related PRs

  • full-bars/connect#1: Extends the same backend-degradation, throttling, transport, transfer, and regression-test code paths.
  • full-bars/connect#2: Shares the backend-degradation tests and log_throttle.go implementation for failure gating, retry backoff, and throttled logging.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title does not describe the main changes, which add backend degradation handling, contract gating, and throttled error logging. Replace the title with a concise summary such as "Add backend degradation gating and throttled error logging".
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upstream/outage-bandwidth-leak

Comment @coderabbitai help to get the list of available commands.

@full-bars full-bars changed the title review: outage bandwidth leak (mirrors upstream #191) review: outage bandwidth leak staging mirror Aug 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@log_throttle_test.go`:
- Around line 71-96: Update the concurrent throttling test to retain the
suppression count returned by the initial allowed call, then add it to the
suppression count from the later Allow call before asserting the total equals
callers-1. Keep the existing schedule-independent emission assertion and
allowed-result checks unchanged.

In `@transfer.go`:
- Around line 3354-3367: Update the CreateContract gate in the transfer loop to
allow one process-wide, rate-limited recovery probe while isBackendDegraded()
remains true, suppressing all other contract requests. Reuse the existing
backend degradation/success tracking mechanisms so a successful probe clears the
degraded state, and add an integration test covering OOB recovery without
reconnecting the authenticated transport.

In `@transport.go`:
- Around line 196-201: Protect noteBackendSuccess with backendFailMu so
resetting consecutiveBackendFails and lastBackendFailNano is serialized with
failure updates and cannot leave a positive failure count with a zero timestamp.
Add a concurrent success-and-failure test that exercises the transition and
asserts isBackendDegraded does not observe this invalid state.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a43d032-403d-42cf-b020-16e514de1b46

📥 Commits

Reviewing files that changed from the base of the PR and between 9dc9531 and d6f78cb.

📒 Files selected for processing (7)
  • backend_degraded_gate_test.go
  • backend_degraded_test.go
  • log_throttle.go
  • log_throttle_test.go
  • transfer.go
  • transfer_contract_manager.go
  • transport.go

Comment thread log_throttle_test.go Outdated
Comment thread transfer.go
Comment on lines +3354 to +3367
// Skip the request entirely while the backend is unreachable. Each
// CreateContract is an OOB control round-trip; with the API down
// every one of them fails, and on a provider carrying many
// sequences that is a continuous storm of requests that cannot
// succeed. The loop still waits out the retry interval, so the
// sequence resumes promptly once a successful auth or OOB
// round-trip clears the degraded state.
if !isBackendDegraded() {
self.client.ContractManager().CreateContract(
contractKey,
self.contractSeqIndex,
ByteCount(32+float32(messageByteCount+messageByteCount+self.sendBufferSettings.MinMessageByteCount)/self.sendBufferSettings.ContractFillFraction),
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Keep one bounded recovery probe while degraded.

Lines 3354-3367 suppress every CreateContract request. A successful OOB result is the only OOB path that calls noteBackendSuccess in transfer_contract_manager.go Lines 1309-1311. If the OOB service recovers while an authenticated transport stays connected, no request observes recovery and the degraded gate remains active indefinitely.

Permit one process-wide, rate-limited contract probe while degraded. Keep all other contract requests suppressed. Add an integration test that recovers OOB service without reconnecting the transport.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@transfer.go` around lines 3354 - 3367, Update the CreateContract gate in the
transfer loop to allow one process-wide, rate-limited recovery probe while
isBackendDegraded() remains true, suppressing all other contract requests. Reuse
the existing backend degradation/success tracking mechanisms so a successful
probe clears the degraded state, and add an integration test covering OOB
recovery without reconnecting the authenticated transport.

Comment thread transport.go Outdated
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

@full-bars
full-bars force-pushed the upstream/outage-bandwidth-leak branch from d6f78cb to 22dedba Compare August 5, 2026 06:19
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

✅ Unit tests committed locally. Commit: 9de2399eef40ae568b711021c9b32092750bb399

…idth during control-API outages

When the control API is unreachable, providers keep creating contracts,
expanding client windows and retransmitting against an endpoint that cannot
authorize anything. The work has nowhere to go, so it is spent bandwidth. On
metered links a sustained outage can consume a large share of a monthly
allowance while serving no client.

Add a shared degradation signal driven by the two round-trips that actually
touch the backend (platform auth and contract OOB). It requires
backendDegradedFailThreshold consecutive failures with no intervening success,
and the last failure must be within backendDegradedWindow, so isolated
timeouts on a busy provider never trip it. Any successful round-trip clears it
immediately, so recovery is not on a timer.

While degraded:
- skip CreateContract; every request is an OOB round-trip that cannot succeed
- start contract retries at the backed-off interval instead of the fast first
  retry, composing with the existing nextCreateContractRetryInterval backoff
- do not expand the multi-client window; each added client needs its own
  contract

Also rate-limit the four log lines that flood under the same fault
([t]auth error, [contract]oob err, [ts]->error, [r]drop) to one per minute
with a suppressed count, via a small shared logThrottle. These are emitted per
sequence per retry, so during an outage they are the dominant log volume and
can push out the lines needed to diagnose it. Each falls back to -v=1 so no
detail is lost when the level is raised.
@full-bars
full-bars force-pushed the upstream/outage-bandwidth-leak branch from 9de2399 to ae61167 Compare August 5, 2026 06:44
The auth sites recorded every connect() error as a backend failure,
including context cancellation from this process's own teardown. Closing
a multi-client window cancels many transports mid-dial at once, and that
burst of canceled dials tripped the degraded threshold with fresh
timestamps -- so the NEXT session started gated, skipping its first
CreateContract per sequence until the first auth success cleared it.
Both auth sites now make the same local-teardown carve-out the contract
OOB path already makes on client.Done, pinned for both transports by a
call-site anchor test.

Also from review, documentation only: isBackendDegraded now describes
the OOB-only-outage steady state honestly (recovery rides the recency
window as a bounded probe cycle, since the gated CreateContract is the
only success source once auth stops re-running); the process-wide
counter names its multi-platform-url limitation and the keying upgrade
path; and noteBackendSuccess loses a duplicated doc line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@full-bars
full-bars merged commit fb87085 into main Aug 6, 2026
1 check passed
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.

2 participants