Goal
Bound ActionCable setup and repair streaming cleanup/reconnect lifecycle
Evidence at frozen review baseline
oilpriceapi/streaming/client.py:130 applies open_timeout to websocket connect, then awaits welcome and subscription confirmation without a deadline. A fake connected socket whose recv never completes exceeded the configured open timeout; cancellation left that socket open. In _iterate, a failed reconnect inside the ConnectionClosed handler escapes instead of using remaining attempts: a local probe raised OSError after one attempt with max_reconnect_attempts=10.
Smallest change / deletion first
Keep the existing stream abstraction. Add one bounded setup lifecycle and reliable cleanup; remove duplicated or ineffective retry branches. Do not build a new streaming framework or background supervisor.
Acceptance and negative-path proof
Risk, delivery and rollback
MEDIUM — SDK connection lifecycle; preserve compatibility and bounded resource use.
Planning only. Reproduce against current main and check intervening/duplicate work before implementation. One focused reversible PR per admitted change, independent adversarial review, ordered merge and approved release/publish with artifact proof. If no change is needed, close with evidence. Rollback must preserve customer data and restore only a known-safe version; do not restore an unsafe public entrypoint to resolve an ownership question.
Parent plan: https://github.com/OilpriceAPI/oilpriceapi-api/issues/8015 . No application changes, remote abuse probes or production writes were made during this audit.
Goal
Bound ActionCable setup and repair streaming cleanup/reconnect lifecycle
Evidence at frozen review baseline
oilpriceapi/streaming/client.py:130 applies open_timeout to websocket connect, then awaits welcome and subscription confirmation without a deadline. A fake connected socket whose recv never completes exceeded the configured open timeout; cancellation left that socket open. In _iterate, a failed reconnect inside the ConnectionClosed handler escapes instead of using remaining attempts: a local probe raised OSError after one attempt with max_reconnect_attempts=10.
Smallest change / deletion first
Keep the existing stream abstraction. Add one bounded setup lifecycle and reliable cleanup; remove duplicated or ineffective retry branches. Do not build a new streaming framework or background supervisor.
Acceptance and negative-path proof
Risk, delivery and rollback
MEDIUM — SDK connection lifecycle; preserve compatibility and bounded resource use.
Planning only. Reproduce against current main and check intervening/duplicate work before implementation. One focused reversible PR per admitted change, independent adversarial review, ordered merge and approved release/publish with artifact proof. If no change is needed, close with evidence. Rollback must preserve customer data and restore only a known-safe version; do not restore an unsafe public entrypoint to resolve an ownership question.
Parent plan: https://github.com/OilpriceAPI/oilpriceapi-api/issues/8015 . No application changes, remote abuse probes or production writes were made during this audit.