Skip to content

Report a transport connection's failure the way a stream connection's is reported - #3273

Merged
mgravell merged 1 commit into
StackExchange:mainfrom
MDA2AV:transport-close-reports-failure
Oct 13, 2026
Merged

mgravell merged 1 commit into
StackExchange:mainfrom
MDA2AV:transport-close-reports-failure

Conversation

@MDA2AV

@MDA2AV MDA2AV commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Context: integrating the experimental transport seam on ioxide (io_uring runtime) at https://github.com/MDA2AV/ioxide/tree/main/src/clients/ioxide.redis.stackexchange

Issue: when not using the stock transport, there is no notification when a connection dies, ConnectionFailed is not raised and commands awaiting a reply are cancelled insterad of failing with RedisConnectionException.

How this PR fixes it: RecordConnectionFailed only reports failure when _ioStream is set, adding _transportAdopted for when another transport is used instead.

Some more context:

IoxideTunnel.ConnectTransportAsync returns IoxideTransport so StackExchange.Redis takes the transport path and not the stream path, _ioStream stay null for the connection's life.
When the connection dies the check sees that _ioStream is null so the reporting is skipped.

@MDA2AV
MDA2AV marked this pull request as ready for review October 12, 2026 20:49
@mgravell
mgravell merged commit 209c46b into StackExchange:main Oct 13, 2026
5 checks passed
@mgravell

Copy link
Copy Markdown
Collaborator

LGTM; I'm interested how ioxide has found this - I'm assuming this is broadly similar to how SocketSet spikes this, but if ioxide does it better: great!

@mgravell

Copy link
Copy Markdown
Collaborator

@MDA2AV also: to emphasize - this API is deliberately [Experimental] precisely because I'm very interested in any "this doesn't fit" etc feedback; I used SocketSet to do a random test, but if you have feedback: throw it at me! Also, if you're looking for things to test against: GarnetServer also has a fairly extensible network API - see SocketSet.Garnet - it might be of interest to you.

@MDA2AV

MDA2AV commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

LGTM; I'm interested how ioxide has found this - I'm assuming this is broadly similar to how SocketSet spikes this, but if ioxide does it better: great!

Thanks, it actually fits quite well and the intergration was simpler than I expected. ioxide is a shared-nothing, thread-per-core runtime, so there is one io_uring ring per reactor (worker), and each reactor gets its own multiplexer. The difference from something like System.Net.Sockets is that ioxide has QUIC and HTTP/3 built in, on the same rings, through sans-I/O libraries like ngtcp2 and nghttp3, and it is built to be web facing rather than to run behind a proxy or gateway. Like SocketSet, it offers kTLS as an option on top of OpenSSL, and it can also use io_uring's zero-copy send.

The main difference from SocketSet is that the code calling SE.Redis also runs on the reactor, so a flush needs no wake and the await resumes on the same thread. I have some benchmarks against SE.Redis's own sockets and some public networking I/O benchmarks vs Rust/Zig/C solutions.

ioxide is io_uring only though, so there is no support for Windows or Mac. imo io_uring can't work well with the work-stealing model, so adding io_uring to System.Net.Sockets doesn't make sense: the performance won't be any better than epoll. It needs a completely different approach at the runtime level.

So, to sum up: since I can't use the existing thread-pool-based (hopping) libraries for C# like HttpClient, the pg drivers and the Redis clients (all on System.Net.Sockets) without losing what ioxide gives me, a library like this one that allows replacing the transport is ideal and very easy to plug into. Trying to use io_uring with the current threadpool work delegating APIs is inefficient and the only way to compete(and beat) Rust is changing the game with inline single threaded shards that use IValueTaskSource and fine control suspensions and continuations to avoid most of Task allocations, state machines and thread hopping state transfer and management.

These are some early non public AI draft docs for ioxide including how redis is integrated if this is of interest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants