Skip to content

Commit c9480b8

Browse files
committed
Add Hyperliquid stale stream recovery
- Add opt-in recovery with targeted resubscribe and reconnect - Preserve `l2Book` options and skip unsubscribed BBO recovery - Expose Python config knobs and document recovery behavior - Related to #4298
1 parent 634cb3a commit c9480b8

10 files changed

Lines changed: 1160 additions & 62 deletions

File tree

RELEASES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ releases as feedback arrives, before the final `2.0.0` release.
3232
- Added Ulcer Index, Omega Ratio, VaR, and Expected Shortfall portfolio statistics (#4352), thanks @Martingale42
3333
- Added Tail Ratio portfolio statistic (#4341), thanks @Martingale42
3434
- Added Hyperliquid market data stream health warnings for stalled Deltas, Depth10, and Quote subscriptions (#4298)
35+
- Added Hyperliquid opt-in stale stream recovery with targeted resubscribe and reconnect escalation (#4298)
3536
- Added Interactive Brokers PyO3 type stub annotations (#4350), thanks @dfjmax
3637

3738
### Breaking Changes

crates/adapters/hyperliquid/src/config.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ use crate::common::{
2424
};
2525

2626
/// Configuration for the Hyperliquid data client.
27+
///
28+
/// The `stale_stream_*` options control the stream health monitor. With recovery
29+
/// enabled, a stale stream is warned about first, targeted-resubscribed once per
30+
/// recovery cooldown (preserving its original `l2Book` options), and escalated to
31+
/// a full WebSocket reconnect after `stale_stream_max_targeted_resubscribes`
32+
/// failed attempts; fresh data resets the ladder. See the Hyperliquid integration
33+
/// guide ("Stream health and recovery") for details.
2734
#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
2835
#[serde(default, deny_unknown_fields)]
2936
#[cfg_attr(
@@ -67,6 +74,18 @@ pub struct HyperliquidDataClientConfig {
6774
/// Cooldown in seconds between stale warnings for the same market-data stream.
6875
#[builder(default = 60)]
6976
pub stale_stream_warning_cooldown_secs: u64,
77+
/// Enables automated stale-stream recovery. Off by default: the stream health
78+
/// monitor warns only and never changes subscriptions.
79+
#[builder(default = false)]
80+
pub stale_stream_recovery_enabled: bool,
81+
/// Cooldown in seconds between recovery actions for the same market-data stream.
82+
/// Must be positive for recovery to run.
83+
#[builder(default = 120)]
84+
pub stale_stream_recovery_cooldown_secs: u64,
85+
/// Targeted resubscribe attempts for a stale stream before escalating to a
86+
/// full WebSocket reconnect.
87+
#[builder(default = 3)]
88+
pub stale_stream_max_targeted_resubscribes: u32,
7089
/// Interval for refreshing instruments in minutes.
7190
#[builder(default = 60)]
7291
pub update_instruments_interval_mins: u64,
@@ -270,6 +289,9 @@ transport_backend = "tungstenite"
270289
assert_eq!(config.stale_stream_receive_timeout_secs, 120);
271290
assert_eq!(config.stream_health_check_interval_secs, 15);
272291
assert_eq!(config.stale_stream_warning_cooldown_secs, 60);
292+
assert!(!config.stale_stream_recovery_enabled);
293+
assert_eq!(config.stale_stream_recovery_cooldown_secs, 120);
294+
assert_eq!(config.stale_stream_max_targeted_resubscribes, 3);
273295
}
274296

275297
#[rstest]
@@ -279,13 +301,19 @@ transport_backend = "tungstenite"
279301
stale_stream_receive_timeout_secs = 30
280302
stream_health_check_interval_secs = 5
281303
stale_stream_warning_cooldown_secs = 20
304+
stale_stream_recovery_enabled = true
305+
stale_stream_recovery_cooldown_secs = 45
306+
stale_stream_max_targeted_resubscribes = 5
282307
",
283308
)
284309
.unwrap();
285310

286311
assert_eq!(config.stale_stream_receive_timeout_secs, 30);
287312
assert_eq!(config.stream_health_check_interval_secs, 5);
288313
assert_eq!(config.stale_stream_warning_cooldown_secs, 20);
314+
assert!(config.stale_stream_recovery_enabled);
315+
assert_eq!(config.stale_stream_recovery_cooldown_secs, 45);
316+
assert_eq!(config.stale_stream_max_targeted_resubscribes, 5);
289317
}
290318

291319
#[rstest]

0 commit comments

Comments
 (0)