WebSocket Disconnect/Reconnect
Expected behavior
- WebSocket reconnect is automatic with exponential backoff (cap: 60 seconds)
- All subscriptions are restored after every reconnect
on_stale/on_recoveredcallbacks continue to fire correctly across reconnects
Common symptoms
- Ticks stop suddenly
- Short data gaps during reconnect
on_stalefires buton_recoverednever fires
Detecting a stale feed
The library detects feed silence automatically. Use on_stale and on_recovered callbacks:
async def on_stale() -> None:
print("No tick for 30s — feed is stale")
# halt algo, alert, etc.
async def on_recovered() -> None:
print("Feed recovered")
await broker.subscribe(watch, on_tick, on_stale=on_stale, on_recovered=on_recovered)
Or poll broker.feed_state directly:
from tt_connect.enums import FeedState
while True:
if broker.feed_state == FeedState.STALE:
print("Feed stale — waiting")
elif broker.feed_state == FeedState.CONNECTED:
pass # healthy
await asyncio.sleep(5)
Per-instrument staleness
from datetime import datetime, timezone, timedelta
IST = timezone(timedelta(hours=5, minutes=30))
ts = broker.last_tick_at(reliance)
if ts:
age = (datetime.now(IST) - ts).total_seconds()
if age > 60:
print(f"No RELIANCE tick for {age:.0f}s")
When on_stale fires but on_recovered never fires
- Market is closed — no ticks are sent outside exchange hours; this is expected
- Subscribed to wrong instrument — verify the symbol resolves to an actively traded contract
- Connection is permanently dropped — check
broker.feed_stateforRECONNECTING; if stuck, the broker endpoint may be down
Callback exceptions hide errors
If your on_tick raises, the stream continues but the exception is only logged. Always wrap business logic:
async def on_tick(tick):
try:
process(tick)
except Exception as e:
logger.error("tick processing failed", exc_info=e)