Skip to content

Commit 3980546

Browse files
userFRMclaude
andcommitted
fix(streaming): post-release follow-ups for v8.0.30 streaming (closes #498)
Closes seven hygiene gaps surfaced by the v8.0.30 review: - Dispatcher drain loop now wraps user-callback invocation in catch_unwind. A panic from user code (Rust closure / PyO3 callable / napi ThreadsafeFunction / C extern fn) no longer kills the dispatcher thread; panics are counted on a new panic_count AtomicU64 (exposed via StreamingDispatcher::panic_count) and logged at error level, then the loop continues. SSOT: every binding inherits this behavior, no per-binding panic handling. - FPSS C ABI handle gains a permanent state field (Fresh / Active / Shutdown). tdx_fpss_set_callback / _set_inline_callback / _reconnect / _shutdown now enforce one-shot registration and terminal shutdown; post-shutdown calls return -1 with a clear tdx_last_error() string. - Unified C ABI: tdx_unified_set_callback after stop is documented as REPLACEMENT (high-level path supports stop+restart). Contract divergence from FPSS one-shot is intentional and now explicit in rustdoc + thetadx.h. - thetadx.h documents ctx lifetime + queued-vs-inline thread affinity on every set_callback / set_inline_callback declaration, mirrored in the thetadx.hpp doxygen blocks. - Python dropped_event_count rustdoc, README, and test corrected to the actual reset-on-reconnect / zero-after-stop semantics. Counter lives on the live StreamingDispatcher; reconnect rebuilds it and resets to 0. Snapshot before reconnect for cross-session accumulation. Matches the TypeScript binding. - Dispatcher dropped counter is now strictly queue-full (TrySendError::Full). TrySendError::Disconnected (rare; happens during shutdown races) feeds a separate disconnected_count so the user-facing drop metric is not inflated by lifecycle noise. - TypeScript index.d.ts regenerated from the corrected napi-rs rustdoc so the JS-visible doc matches the Rust source. Version 8.0.30 -> 8.0.31 via scripts/bump_version.py. Closes #498 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 45cc5de commit 3980546

27 files changed

Lines changed: 803 additions & 190 deletions

File tree

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,44 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [8.0.31] - 2026-05-06
9+
10+
### Fixed
11+
12+
- **StreamingDispatcher drain loop now catches user-callback panics**
13+
and continues serving subsequent events. New `panic_count`
14+
diagnostic counter exposed alongside `dropped_count`. Previously a
15+
panic in user code (Rust closure / PyO3 callable / napi
16+
ThreadsafeFunction / C extern fn) silently killed the dispatcher
17+
thread; only `shutdown()` surfaced it.
18+
- **FPSS C ABI handle state machine.** `tdx_fpss_set_callback` /
19+
`_inline_callback` / `_reconnect` / `_shutdown` enforce the public
20+
contract: at most one registration per handle, shutdown is
21+
terminal, post-shutdown ops return -1 with a clear `tdx_last_error()`
22+
string. Previously the contract was documented but unenforced.
23+
- **C ABI `ctx` lifetime contract documented.** The public header now
24+
states `ctx` must outlive registration until shutdown / free
25+
returns (or a successful unified re-registration). Queued vs inline
26+
thread-affinity also documented.
27+
- **Python `dropped_event_count()` doc + test corrected** to
28+
reflect the actual reset-on-reconnect / zero-after-stop semantics.
29+
The counter lives on the StreamingDispatcher and resets when the
30+
dispatcher is rebuilt (matches the TypeScript binding).
31+
- **Dispatcher `dropped` counter is now strictly queue-full.** The
32+
`Disconnected` variant of `TrySendError` (rare; happens only during
33+
shutdown races) feeds a new separate `disconnected_count` so the
34+
user-facing drop metric isn't inflated by lifecycle noise.
35+
- **TypeScript `index.d.ts` regenerated** so the JS-visible doc
36+
comment matches the Rust source — the counter resets on reconnect.
37+
38+
### Changed
39+
40+
- **Unified C ABI `set_callback` after stop is REPLACEMENT.** Documented
41+
explicitly in `thetadx.h` and the rustdoc: contrary to the FPSS
42+
one-shot rule, the unified high-level path supports stop +
43+
re-register as a normal user flow (this is what `reconnect_streaming`
44+
is built on). The contract divergence is intentional.
45+
846
## [8.0.30] - 2026-05-06
947

1048
This release closes #482: the entire FPSS streaming stack — Rust core,

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/thetadatadx/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thetadatadx"
3-
version = "8.0.30"
3+
version = "8.0.31"
44
edition.workspace = true
55
rust-version.workspace = true
66
authors.workspace = true

0 commit comments

Comments
 (0)