feat: always-on reconnect replay buffer with data integrity verification#63
Merged
Conversation
- Updated API index to include new classes: StreamMultiplexer, ReadChannel, WriteChannel, Errors, and StreamPair. - Expanded concepts index to cover Graceful Shutdown, Heartbeat, and Flush Modes. - Added detailed documentation for Errors and Exceptions, including MultiplexerException and ChannelClosedException. - Introduced ReadChannel and WriteChannel documentation, outlining usage, properties, and events. - Created StreamMultiplexer and StreamPair documentation, detailing lifecycle, channel operations, and advanced methods. - Added Flush Modes documentation to explain buffering behavior and configuration options. - Documented Graceful Shutdown protocol and its implementation in multiplexer operations. - Included Heartbeat mechanism for connection health monitoring and RTT measurement.
- Introduced HoldableWriteStream to simulate OS socket send buffer behavior, allowing writes to be held and dropped to test data loss scenarios. - Implemented InFlightLossDuplexPipe to utilize HoldableWriteStream for simulating in-flight data loss during disconnects. - Updated DisconnectionDataLossTests to validate data integrity and reconnection mechanics with in-flight data scenarios. - Enhanced existing tests to ensure all data is received correctly after disconnects, including baseline, in-flight, and post-reconnect data. - Added new test for verifying data loss when using HoldableWriteStream during disconnects.
- Replace opt-in ReconnectBufferSize with always-on ring buffer sized from MaxCredits - ChannelSyncState records all sent data; replays unacknowledged bytes on reconnect - Fix off-by-one in ProcessReconnectAckFrame offset calculation - Fix PipeReader AdvanceTo deadlock in ReadSingleFrameAsync - Fix test reconnect race with PrepareReconnectWait pattern - Update docs: Data Integrity section, MaxCredits dual-role notes, event descriptions - Fix incorrect doc claim that credit grants trim the ring buffer - Strengthen 3 data integrity tests to verify content, not just byte count - Update benchmarks for WriteChannel constructor signature change
- Add [Trait("Category", "HighMemory")] to DisconnectionDataLossTests
so it is properly excluded from the main test batch
- Replace hardcoded HighMemory class array with dynamic file scanning
using Regex to discover classes with [Trait("Category", "HighMemory")]
- Add UseLocalNetConduit=true to TestEntry build step so integration
tests compile against local source instead of NuGet v2.1.1 which
lacks the OpenChannelAsync(string) overload
- BuildEntry remains UseLocalNetConduit=false for NuGet packaging
52d7e0c to
e1c7e85
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the opt-in
ReconnectBufferSizewith an always-on per-channel ring buffer sized fromMaxCredits(4MB default). On reconnection, unacknowledged in-flight data is automatically replayed — no data is silently lost.Changes
Core (src/NetConduit)
GetUnacknowledgedDataFrom()replays unacked bytes on reconnectChannelSyncStatesized toMaxCredits, callsStartRecording()unconditionallyWaitForReconnectPositionsAndReplayAsync+ReplayUnacknowledgedDataToStreamAsyncfor reconnect protocolReadSingleFrameAsyncPipeReaderAdvanceTodeadlockTests (tests/NetConduit.UnitTests)
OnReconnectedhandlers BEFORE disconnect to fix race conditionDocumentation (docs/)
MaxCreditsdual-role note (credit window + replay buffer)OnReconnectedupdated with replay contextMaxCreditsreconnection linkBenchmarks
WriteChannelconstructor signature changeTesting
DisconnectionDataLossTestspass