From 50d8140cd5932c8ccdd73fb07598ec870eca57e2 Mon Sep 17 00:00:00 2001 From: preview Date: Thu, 2 Jul 2026 17:43:08 +0200 Subject: [PATCH 1/5] fix(streaming): default read timeout to 10s to match the terminal The streaming read timeout default was 3s while the terminal's streaming client uses a 10s socket read timeout before treating a silent connection as dead and reconnecting. Right after subscribing to a full-market stream the server can go a few seconds fully silent (no data, no heartbeat) while it sets up the subscription; the 3s deadline trips inside that gap and forces an unnecessary reconnect. The 10s deadline rides through it. The knob stays configurable via streaming.timeout_ms. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 4 ++++ .../include/config_accessors.hpp.inc | 4 ++-- thetadatadx-cpp/include/thetadatadx.h | 4 ++-- thetadatadx-ffi/src/auth.rs | 2 +- thetadatadx-ffi/src/config_accessors.rs | 4 ++-- .../python/thetadatadx/__init__.pyi | 2 +- .../src/_generated/config_accessors.rs | 4 ++-- .../tests/test_config_resilience.py | 6 +++--- thetadatadx-rs/config.default.toml | 8 +++++--- thetadatadx-rs/config_surface.toml | 16 ++++++++-------- thetadatadx-rs/src/config/fpss.rs | 19 ++++++++++++------- thetadatadx-rs/src/config/mod.rs | 2 +- thetadatadx-ts/index.d.ts | 4 ++-- .../src/_generated/config_accessors.rs | 4 ++-- 14 files changed, 47 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e00020ad..a71c0e80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [13.0.0-rc.13] - 2026-07-02 +### Changed + +- The default streaming read timeout is now 10s (was 3s), matching the terminal's streaming socket read timeout so a client rides through the brief silence right after a full-market subscribe instead of tripping the deadline and forcing an unnecessary reconnect. Still configurable via `streaming.timeout_ms`. + ### Fixed - **Windows server archive attaches to the release.** The Windows `thetadatadx-server` archive was built, but the upload step received a path the artifact action could not resolve on Windows, so the GitHub Release carried no Windows binary. The archive is now referenced by its native workspace path and attaches correctly. diff --git a/thetadatadx-cpp/include/config_accessors.hpp.inc b/thetadatadx-cpp/include/config_accessors.hpp.inc index 18b20e0e..55179e1e 100644 --- a/thetadatadx-cpp/include/config_accessors.hpp.inc +++ b/thetadatadx-cpp/include/config_accessors.hpp.inc @@ -81,13 +81,13 @@ } /// Set the streaming read timeout (ms): the no-frames deadline after - /// which the streaming I/O loop reconnects. Default 3_000; + /// which the streaming I/O loop reconnects. Default 10_000; /// validated to [100, 60_000] at connect. void set_streaming_timeout_ms(std::uint64_t v) { thetadatadx_config_set_streaming_timeout_ms(handle_.get(), v); } - /// Current streaming timeout_ms (default 3_000). + /// Current streaming timeout_ms (default 10_000). std::uint64_t get_streaming_timeout_ms() const { std::uint64_t out{}; thetadatadx_config_get_streaming_timeout_ms(handle_.get(), &out); diff --git a/thetadatadx-cpp/include/thetadatadx.h b/thetadatadx-cpp/include/thetadatadx.h index 0763b16c..6bcbac72 100644 --- a/thetadatadx-cpp/include/thetadatadx.h +++ b/thetadatadx-cpp/include/thetadatadx.h @@ -1452,7 +1452,7 @@ int32_t thetadatadx_config_set_reconnect_callback(ThetaDataDxConfig* config, The /** * Set the streaming read timeout (ms): the no-frames deadline after which - * the streaming session is declared dead and reconnects. Default 3_000; + * the streaming session is declared dead and reconnects. Default 10_000; * validated to [100, 60_000] at connect. * @param config Config handle to mutate; no-op when NULL. * @param v Read timeout in milliseconds. @@ -1460,7 +1460,7 @@ int32_t thetadatadx_config_set_reconnect_callback(ThetaDataDxConfig* config, The void thetadatadx_config_set_streaming_timeout_ms(ThetaDataDxConfig* config, uint64_t v); /** - * Read the current streaming timeout_ms setting (default 3_000). + * Read the current streaming timeout_ms setting (default 10_000). * @param config Config handle to read. * @param out Receives the timeout in milliseconds on success. * @return 0 on success, -1 if either pointer is null. diff --git a/thetadatadx-ffi/src/auth.rs b/thetadatadx-ffi/src/auth.rs index 0678f396..1f8e8a1d 100644 --- a/thetadatadx-ffi/src/auth.rs +++ b/thetadatadx-ffi/src/auth.rs @@ -2189,7 +2189,7 @@ mod resilience_knob_tests { super::thetadatadx_config_get_streaming_timeout_ms(cfg, &mut got), 0 ); - assert_eq!(got, 3_000); + assert_eq!(got, 10_000); super::thetadatadx_config_set_streaming_timeout_ms(cfg, 9_000); assert_eq!( super::thetadatadx_config_get_streaming_timeout_ms(cfg, &mut got), diff --git a/thetadatadx-ffi/src/config_accessors.rs b/thetadatadx-ffi/src/config_accessors.rs index 6dffc019..2cf61a60 100644 --- a/thetadatadx-ffi/src/config_accessors.rs +++ b/thetadatadx-ffi/src/config_accessors.rs @@ -230,7 +230,7 @@ pub unsafe extern "C" fn thetadatadx_config_get_reconnect_replay_pace_ms( }) } -/// Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `3_000`; validated to `[100, 60_000]` at connect. +/// Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `10_000`; validated to `[100, 60_000]` at connect. #[no_mangle] pub unsafe extern "C" fn thetadatadx_config_set_streaming_timeout_ms( config: *mut ThetaDataDxConfig, @@ -242,7 +242,7 @@ pub unsafe extern "C" fn thetadatadx_config_set_streaming_timeout_ms( }) } -/// Read the current streaming `timeout_ms` setting (default `3_000`). +/// Read the current streaming `timeout_ms` setting (default `10_000`). /// /// Writes the configured value into `*out`. Returns `0` on success, /// `-1` if either pointer is null. diff --git a/thetadatadx-py/python/thetadatadx/__init__.pyi b/thetadatadx-py/python/thetadatadx/__init__.pyi index d40a9f4d..d0582a75 100644 --- a/thetadatadx-py/python/thetadatadx/__init__.pyi +++ b/thetadatadx-py/python/thetadatadx/__init__.pyi @@ -264,7 +264,7 @@ class Config: metrics_port: Optional[int] """Prometheus exporter port. ``None`` (the default) leaves the exporter disabled even when the metrics feature is compiled in; an ``int`` binds an HTTP listener on ``0.0.0.0:``. The setter raises ``ValueError`` for values outside ``0..=65535``.""" streaming_timeout_ms: int - """No-frames deadline, in milliseconds, for the streaming connection (default 3_000).""" + """No-frames deadline, in milliseconds, for the streaming connection (default 10_000).""" streaming_connect_timeout_ms: int """Connect timeout, in milliseconds, for opening a streaming connection.""" streaming_ping_interval_ms: int diff --git a/thetadatadx-py/src/_generated/config_accessors.rs b/thetadatadx-py/src/_generated/config_accessors.rs index c86deaff..097285c2 100644 --- a/thetadatadx-py/src/_generated/config_accessors.rs +++ b/thetadatadx-py/src/_generated/config_accessors.rs @@ -104,14 +104,14 @@ impl Config { /// Set the streaming read timeout (ms): the no-frames deadline after /// which the streaming I/O loop declares the session dead and - /// reconnects. Default ``3_000``; validated to ``[100, 60_000]``. + /// reconnects. Default ``10_000``; validated to ``[100, 60_000]``. #[setter] fn set_streaming_timeout_ms(&self, ms: u64) { let mut guard = self.inner.lock().unwrap_or_else(|e| e.into_inner()); guard.streaming.timeout_ms = ms; } - /// Current ``streaming.timeout_ms`` value (default ``3_000``). + /// Current ``streaming.timeout_ms`` value (default ``10_000``). #[getter] fn get_streaming_timeout_ms(&self) -> u64 { let guard = self.inner.lock().unwrap_or_else(|e| e.into_inner()); diff --git a/thetadatadx-py/tests/test_config_resilience.py b/thetadatadx-py/tests/test_config_resilience.py index 92045946..be2d29dc 100644 --- a/thetadatadx-py/tests/test_config_resilience.py +++ b/thetadatadx-py/tests/test_config_resilience.py @@ -97,7 +97,7 @@ def test_reconnect_callback_registration_switches_policy(): def test_streaming_transport_defaults_and_round_trip(): mod = _import_module() cfg = mod.Config.production() - assert cfg.streaming_timeout_ms == 3_000 + assert cfg.streaming_timeout_ms == 10_000 assert cfg.streaming_connect_timeout_ms == 2_000 assert cfg.streaming_ping_interval_ms == 250 assert cfg.streaming_ring_size == 131_072 @@ -105,7 +105,7 @@ def test_streaming_transport_defaults_and_round_trip(): assert cfg.streaming_keepalive_idle_secs == 5 assert cfg.streaming_keepalive_interval_secs == 2 assert cfg.streaming_keepalive_retries == 2 - cfg.streaming_timeout_ms = 10_000 + cfg.streaming_timeout_ms = 15_000 cfg.streaming_connect_timeout_ms = 5_000 cfg.streaming_ping_interval_ms = 1_000 cfg.streaming_ring_size = 8_192 @@ -113,7 +113,7 @@ def test_streaming_transport_defaults_and_round_trip(): cfg.streaming_keepalive_idle_secs = 10 cfg.streaming_keepalive_interval_secs = 5 cfg.streaming_keepalive_retries = 4 - assert cfg.streaming_timeout_ms == 10_000 + assert cfg.streaming_timeout_ms == 15_000 assert cfg.streaming_connect_timeout_ms == 5_000 assert cfg.streaming_ping_interval_ms == 1_000 assert cfg.streaming_ring_size == 8_192 diff --git a/thetadatadx-rs/config.default.toml b/thetadatadx-rs/config.default.toml index b685aa43..bb907793 100644 --- a/thetadatadx-rs/config.default.toml +++ b/thetadatadx-rs/config.default.toml @@ -36,9 +36,11 @@ hosts = [ connect_timeout = 2000 # Read timeout — how long to wait for data before the link is considered -# dead (ms). The server heartbeats every ~100 ms on a quiet session, so this -# default is ~30 missed heartbeats: a dead link is declared quickly. -read_timeout = 3000 +# dead (ms). Matches the terminal's streaming socket read timeout and rides +# through the brief silence right after a full-market subscribe while the +# server sets the subscription up. The ~100 ms cadence is the client's ping +# to the server, not an inbound heartbeat; inbound frames arrive ~250 ms. +read_timeout = 10000 # Client heartbeat interval (ms). The server's own ~100 ms heartbeat is the # primary liveness signal; this client ping proves write-side health at a diff --git a/thetadatadx-rs/config_surface.toml b/thetadatadx-rs/config_surface.toml index 63416700..b3ebba26 100644 --- a/thetadatadx-rs/config_surface.toml +++ b/thetadatadx-rs/config_surface.toml @@ -324,20 +324,20 @@ param = "v" abi_type = "u64" path = "streaming.timeout_ms" doc = """ -Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `3_000`; validated to `[100, 60_000]` at connect. +Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `10_000`; validated to `[100, 60_000]` at connect. """ cpp_doc = """ Set the streaming read timeout (ms): the no-frames deadline after -which the streaming I/O loop reconnects. Default 3_000; +which the streaming I/O loop reconnects. Default 10_000; validated to [100, 60_000] at connect. """ py_doc = """ Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and -reconnects. Default ``3_000``; validated to ``[100, 60_000]``. +reconnects. Default ``10_000``; validated to ``[100, 60_000]``. """ ts_doc = """ -Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `3_000n`; validated to `[100, 60_000]` at connect. +Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `10_000n`; validated to `[100, 60_000]` at connect. """ py_param = "ms" ts_param = "ms" @@ -349,19 +349,19 @@ param = "out" abi_type = "u64" path = "streaming.timeout_ms" doc = """ -Read the current streaming `timeout_ms` setting (default `3_000`). +Read the current streaming `timeout_ms` setting (default `10_000`). Writes the configured value into `*out`. Returns `0` on success, `-1` if either pointer is null. """ cpp_doc = """ -Current streaming timeout_ms (default 3_000). +Current streaming timeout_ms (default 10_000). """ py_doc = """ -Current ``streaming.timeout_ms`` value (default ``3_000``). +Current ``streaming.timeout_ms`` value (default ``10_000``). """ ts_doc = """ -Current `streaming.timeout_ms` value (default `3_000n`). +Current `streaming.timeout_ms` value (default `10_000n`). """ [[accessor]] diff --git a/thetadatadx-rs/src/config/fpss.rs b/thetadatadx-rs/src/config/fpss.rs index 324a100e..a375f472 100644 --- a/thetadatadx-rs/src/config/fpss.rs +++ b/thetadatadx-rs/src/config/fpss.rs @@ -134,11 +134,16 @@ pub struct StreamingConfig { /// Drives the per-connection initial socket read timeout, the framing /// layer's mid-frame stall budget, and the I/O loop's overall /// "no frames received" deadline that triggers - /// [`crate::RemoveReason::TimedOut`]. Default `3_000` - /// — the server heartbeats every ~100 ms on a quiet session, so - /// three seconds of total silence is ~30 missed heartbeats and a - /// dead link is declared quickly instead of after the previous - /// 10 s default. Validated to the range `[100, 60_000]` ms. + /// [`crate::RemoveReason::TimedOut`]. Default `10_000`, matching the + /// terminal's streaming socket read timeout. Right after a + /// full-market subscribe the server can fall fully silent (no + /// frames, no pings) for a few seconds while it sets the + /// subscription up; a 10 s deadline rides through that gap where a + /// shorter one trips inside it and forces an unnecessary reconnect. + /// The ~100 ms cadence is the client's ping to the server, not an + /// inbound heartbeat; inbound frames and pings arrive roughly every + /// ~250 ms on an active session. Validated to the range + /// `[100, 60_000]` ms. pub timeout_ms: u64, /// Streaming event ring buffer size (slots). @@ -255,7 +260,7 @@ impl StreamingConfig { ], host_selection: HostSelectionPolicy::Shuffled, host_shuffle_seed: None, - timeout_ms: 3_000, + timeout_ms: 10_000, ring_size: 131_072, ping_interval_ms: 250, connect_timeout_ms: 2_000, @@ -301,7 +306,7 @@ mod tests { #[test] fn production_defaults_resilience_shape() { let cfg = StreamingConfig::production_defaults(); - assert_eq!(cfg.timeout_ms, 3_000); + assert_eq!(cfg.timeout_ms, 10_000); assert_eq!(cfg.ping_interval_ms, 250); assert_eq!(cfg.io_read_slice_ms, 25); assert_eq!(cfg.keepalive_idle_secs, 5); diff --git a/thetadatadx-rs/src/config/mod.rs b/thetadatadx-rs/src/config/mod.rs index 3e7a71a0..c5b39418 100644 --- a/thetadatadx-rs/src/config/mod.rs +++ b/thetadatadx-rs/src/config/mod.rs @@ -2013,7 +2013,7 @@ mod tests { let config = DirectConfig::production_defaults(); let validated = config.validate().expect("production defaults validate"); assert_eq!(validated.historical.window_size_kb, 64); - assert_eq!(validated.streaming.timeout_ms, 3_000); + assert_eq!(validated.streaming.timeout_ms, 10_000); assert_eq!(validated.streaming.ping_interval_ms, 250); assert_eq!(validated.streaming.connect_timeout_ms, 2_000); assert_eq!(validated.streaming.io_read_slice_ms, 25); diff --git a/thetadatadx-ts/index.d.ts b/thetadatadx-ts/index.d.ts index d6199465..e8c48e2e 100644 --- a/thetadatadx-ts/index.d.ts +++ b/thetadatadx-ts/index.d.ts @@ -294,9 +294,9 @@ export declare class Config { setReconnectReplayPaceMs(ms: bigint): void /** Current `replay_pace_ms` value (default `5n`). */ get reconnectReplayPaceMs(): bigint - /** Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `3_000n`; validated to `[100, 60_000]` at connect. */ + /** Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `10_000n`; validated to `[100, 60_000]` at connect. */ setStreamingTimeoutMs(ms: bigint): void - /** Current `streaming.timeout_ms` value (default `3_000n`). */ + /** Current `streaming.timeout_ms` value (default `10_000n`). */ get streamingTimeoutMs(): bigint /** Set the per-server connect timeout (ms) for the streaming connection. Default `2_000n`; validated to `[1_000, 60_000]` at connect. */ setStreamingConnectTimeoutMs(ms: bigint): void diff --git a/thetadatadx-ts/src/_generated/config_accessors.rs b/thetadatadx-ts/src/_generated/config_accessors.rs index 88c853ae..b68d4807 100644 --- a/thetadatadx-ts/src/_generated/config_accessors.rs +++ b/thetadatadx-ts/src/_generated/config_accessors.rs @@ -152,7 +152,7 @@ impl Config { Ok(napi::bindgen_prelude::BigInt::from(guard.reconnect.replay_pace_ms)) } - /// Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `3_000n`; validated to `[100, 60_000]` at connect. + /// Set the streaming read timeout (ms): the no-frames deadline after which the streaming I/O loop declares the session dead and reconnects. Default `10_000n`; validated to `[100, 60_000]` at connect. #[napi(js_name = "setStreamingTimeoutMs")] pub fn set_streaming_timeout_ms(&self, ms: napi::bindgen_prelude::BigInt) -> napi::Result<()> { let value = bigint_to_u64("setStreamingTimeoutMs", &ms)?; @@ -164,7 +164,7 @@ impl Config { Ok(()) } - /// Current `streaming.timeout_ms` value (default `3_000n`). + /// Current `streaming.timeout_ms` value (default `10_000n`). #[napi(getter, js_name = "streamingTimeoutMs")] pub fn streaming_timeout_ms(&self) -> napi::Result { let guard = self From 4cbb09a46b12ca1932b1e1b198481cf4e7673e81 Mon Sep 17 00:00:00 2001 From: preview Date: Thu, 2 Jul 2026 17:45:37 +0200 Subject: [PATCH 2/5] docs: mirror CHANGELOG to docs-site Co-Authored-By: Claude Opus 4.8 --- docs-site/docs/changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs-site/docs/changelog.md b/docs-site/docs/changelog.md index e00020ad..a71c0e80 100644 --- a/docs-site/docs/changelog.md +++ b/docs-site/docs/changelog.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [13.0.0-rc.13] - 2026-07-02 +### Changed + +- The default streaming read timeout is now 10s (was 3s), matching the terminal's streaming socket read timeout so a client rides through the brief silence right after a full-market subscribe instead of tripping the deadline and forcing an unnecessary reconnect. Still configurable via `streaming.timeout_ms`. + ### Fixed - **Windows server archive attaches to the release.** The Windows `thetadatadx-server` archive was built, but the upload step received a path the artifact action could not resolve on Windows, so the GitHub Release carried no Windows binary. The archive is now referenced by its native workspace path and attaches correctly. From bef8bcaca10e6da2b534a5b75488cb272fce0801 Mon Sep 17 00:00:00 2001 From: preview Date: Thu, 2 Jul 2026 17:55:58 +0200 Subject: [PATCH 3/5] docs(streaming): reconcile ping_interval_ms liveness wording The ping_interval_ms docs described a server-side ~100ms heartbeat as the primary reverse-direction liveness signal, contradicting the timeout_ms docs. ping_interval_ms is the client's outbound ping (default 250ms); reverse-direction liveness is the inbound frame and ping stream (~250ms) that timeout_ms guards. Co-Authored-By: Claude Opus 4.8 --- thetadatadx-rs/config.default.toml | 5 +++-- thetadatadx-rs/src/config/fpss.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/thetadatadx-rs/config.default.toml b/thetadatadx-rs/config.default.toml index bb907793..efab8ed5 100644 --- a/thetadatadx-rs/config.default.toml +++ b/thetadatadx-rs/config.default.toml @@ -42,9 +42,10 @@ connect_timeout = 2000 # to the server, not an inbound heartbeat; inbound frames arrive ~250 ms. read_timeout = 10000 -# Client heartbeat interval (ms). The server's own ~100 ms heartbeat is the -# primary liveness signal; this client ping proves write-side health at a +# Client outbound ping interval (ms). This ping proves write-side health at a # 4 Hz cadence without adding inbound-frame pressure on a recovering upstream. +# Reverse-direction liveness is the inbound frame and ping stream (~250 ms), +# which read_timeout guards. ping_interval = 250 # Initial reconnect wait after an involuntary disconnect (ms). The auto- diff --git a/thetadatadx-rs/src/config/fpss.rs b/thetadatadx-rs/src/config/fpss.rs index a375f472..5dfcfeda 100644 --- a/thetadatadx-rs/src/config/fpss.rs +++ b/thetadatadx-rs/src/config/fpss.rs @@ -159,14 +159,14 @@ pub struct StreamingConfig { /// Streaming heartbeat ping interval in milliseconds. /// - /// The streaming server expects a heartbeat at this cadence and may - /// disconnect if it falls silent. Default `250` — the server's own - /// ~100 ms heartbeat is the primary liveness signal in the - /// reverse direction; the client ping mainly proves write-side - /// health, and a 4 Hz cadence does that without contributing to - /// inbound-frame pressure on a recovering upstream. Validated to - /// the range `[100, 300_000]` ms — sub-100 ms values are rejected - /// so a misconfiguration does not flood the upstream. + /// This is the client's outbound ping cadence to the server, and the + /// server may disconnect if it falls silent. Default `250` — the ping + /// mainly proves write-side health at a 4 Hz cadence without adding + /// inbound-frame pressure on a recovering upstream. Reverse-direction + /// liveness is the inbound frame and ping stream (~250 ms on an active + /// session), which [`Self::timeout_ms`] guards. Validated to the range + /// `[100, 300_000]` ms — sub-100 ms values are rejected so a + /// misconfiguration does not flood the upstream. pub ping_interval_ms: u64, /// Per-server TCP connect timeout in milliseconds. Default `2000`. From d209e8fec65258571176494c1824f0bf240d58c2 Mon Sep 17 00:00:00 2001 From: preview Date: Thu, 2 Jul 2026 18:10:05 +0200 Subject: [PATCH 4/5] test(ts): update streaming timeout default assertion to 10s The TS config-resilience test still pinned the streaming read timeout default at 3_000n and round-tripped through 10_000n; both now reflect the 10s default, with the setter round-trip moved to 15_000n to stay discriminating. Co-Authored-By: Claude Opus 4.8 --- thetadatadx-ts/__tests__/config_resilience.test.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/thetadatadx-ts/__tests__/config_resilience.test.mjs b/thetadatadx-ts/__tests__/config_resilience.test.mjs index 4f5d008c..026d1fd3 100644 --- a/thetadatadx-ts/__tests__/config_resilience.test.mjs +++ b/thetadatadx-ts/__tests__/config_resilience.test.mjs @@ -67,7 +67,7 @@ test("reconnect callback registration switches policy", () => { test("streaming transport defaults and round-trip", () => { const cfg = Config.production(); - assert.equal(cfg.streamingTimeoutMs, 3_000n); + assert.equal(cfg.streamingTimeoutMs, 10_000n); assert.equal(cfg.streamingConnectTimeoutMs, 2_000n); assert.equal(cfg.streamingPingIntervalMs, 250n); assert.equal(cfg.streamingRingSize, 131_072n); @@ -75,9 +75,9 @@ test("streaming transport defaults and round-trip", () => { assert.equal(cfg.streamingKeepaliveIdleSecs, 5n); assert.equal(cfg.streamingKeepaliveIntervalSecs, 2n); assert.equal(cfg.streamingKeepaliveRetries, 2); - cfg.setStreamingTimeoutMs(10_000n); + cfg.setStreamingTimeoutMs(15_000n); cfg.setStreamingKeepaliveIdleSecs(10n); - assert.equal(cfg.streamingTimeoutMs, 10_000n); + assert.equal(cfg.streamingTimeoutMs, 15_000n); assert.equal(cfg.streamingKeepaliveIdleSecs, 10n); }); From 855a3fa0db90dac09d02e4a947f34e4d4d942caa Mon Sep 17 00:00:00 2001 From: preview Date: Thu, 2 Jul 2026 18:33:31 +0200 Subject: [PATCH 5/5] docs(streaming): correct module read-timeout default to 10s The connection module header still documented a 3 second read-timeout default; the production default is 10 seconds. Co-Authored-By: Claude Opus 4.8 --- thetadatadx-rs/src/fpss/connection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thetadatadx-rs/src/fpss/connection.rs b/thetadatadx-rs/src/fpss/connection.rs index cbe25466..34f294f0 100644 --- a/thetadatadx-rs/src/fpss/connection.rs +++ b/thetadatadx-rs/src/fpss/connection.rs @@ -9,7 +9,7 @@ //! detection) so a peer that vanishes without a FIN/RST is detected //! by the transport long before the platform default of 2+ hours //! - Connect timeout: 2 seconds (configurable) -//! - Read timeout: configurable (default 3 seconds) +//! - Read timeout: configurable (default 10 seconds) //! - Host order: fault-domain-aware per-client shuffle by default (see //! [`order_hosts`]), `FixedOrder` escape hatch preserves declaration //! order