Repository navigation
redis: drop ioxide.redis - #337
Merged
Merged
Conversation
ioxide.redis is weight the project does not want to carry: a whole Redis client to maintain - five open fixes against it - when StackExchange.Redis can run on the reactor's ring instead (#335, ioxide.redis.stackexchange). Removed: the package, its Playground sample (Clients/Redis) and the Env helper only it used, its tests (the Redis suite stays, empty, for the transport's tests), its CI pack step, its bench run and row, its pane on the docs page, and docs/learn's two Redis pages with their links. The passing Redis mentions in the Http3/Nghttp3Buffered sample's comments go too. The versions already on nuget.org are untouched.
MDA2AV
added a commit
that referenced
this pull request
Oct 12, 2026
MDA2AV
added a commit
that referenced
this pull request
Oct 12, 2026
MDA2AV
added a commit
that referenced
this pull request
Oct 12, 2026
This was referenced Oct 12, 2026
MDA2AV
added a commit
that referenced
this pull request
Oct 12, 2026
…d recv has returned (#292) * pg, redis: a timed-out connection is shut down, and freed only once its armed recv has returned A command timeout disposed the connection while its reader was parked on a ring recv: close(fd), then the buffers freed. close() does not end a socket an io_uring op still holds, so the socket stayed ESTABLISHED and the recv stayed armed until the server finally answered, and the kernel then wrote that reply into the freed receive buffer - which the allocator had already handed to the replacement connection (same address, same fd number). Pick's dispose of a connection broken by one loop could hit the other loop's op the same way. Dispose now shuts the socket down while a loop is parked on an op, which completes it, and the loop that exits last closes the fd and frees the buffers. Dispose marks the connection broken, so it takes no new commands in between. "pg:" and "redis: a timed-out connection's socket ends at the timeout, not when the late reply comes" time a command out on the sidecar (pg_sleep(30), BLPOP 30) and require the pool connection that timed out to leave ESTABLISHED within 10 s, while its sibling stays ESTABLISHED and the pool still answers. Confirmed both ways: both fail on the unmodified source (still ESTABLISHED after 10 s) and pass with the fix. * pg-only: the Redis half goes with ioxide.redis (#337)
MDA2AV
added a commit
that referenced
this pull request
Oct 12, 2026
…ing forever (#318) * pg, redis: a connect and its startup or handshake end at CommandTimeoutMs instead of waiting forever Nothing bounded opening a connection. A server that accepted the TCP connection and never answered the pg startup, or a redis AUTH or SELECT, held ConnectAsync forever. A connect whose SYN was never answered waited out the kernel's retries, about two minutes. The pool coalesces opens: the slow path starts one only when none is in flight, and the ticker replenishes only then too. So one open that never finished held off every later one, and a pool left without a live connection parked its queries for good, even after the server recovered. ConnectAsync now arms a ring timeout of CommandTimeoutMs next to the open. If the open is still running when it fires, it shuts the socket down, which completes whatever ring op the open is parked on (connect, send or recv). The open then fails with an error naming the step that stalled, and the pool's existing failure path frees the slot for the next attempt. A finished or failed open disarms it first, so a late expiry never touches an fd that may have been reused. CommandTimeoutMs = 0 still disables it. Sweep cannot do this with what the pool holds: an open in progress is not in _connections, and _opening is only a count. New tests, PgOpenTests and RedisOpenTests, with a 1000 ms timeout. A FakeServer that accepts and never answers must fail the pg startup and the redis handshake (Database 1, so the open sends a SELECT). A listener with a full backlog, which drops the SYN, must fail the pg connect step. For each client, a pool of one whose first open is never answered must connect on its next attempt: the FakeServer forwards later connections to the real server through a new harness Forwarder. Confirmed both ways: all five time out (10 s) on f298af0, and pass with the fix. * pg-only: the Redis half goes with ioxide.redis (#337)
MDA2AV
added a commit
that referenced
this pull request
Oct 12, 2026
…ever its index holds afterwards (#313) * pg, redis: the timeout sweep removes the connection that timed out, not whatever its index holds afterwards Sweep failed a timed-out connection's waiters through CheckTimeout and then removed and disposed _connections[i]. The waiters resume inline, so a handler that queries again picks from the pool inside the sweep, and Pick evicts the timed-out connection, which is broken, shifting the list. Sweep then disposed whatever had moved into index i: a live connection holding the queries just placed on it, which failed with "send failed: errno 9". When the timed-out connection was the last entry, the index was past the end and the ticker faulted, skipping the rest of that sweep. Sweep now holds the connection it checked, removes it by reference (a no-op if a Pick already did), and clamps the index to the list's current length. No new state. New tests, PgSweepTests and RedisSweepTests: a pool of 2 with a 1000 ms command timeout, a pg_sleep(30) or BLPOP for 30 s on index 0, and a handler that issues two more commands when the timeout fails it. The handler records that the timed-out connection is still listed when it runs, which shows it ran inline in the sweep. Confirmed both ways: on f298af0 both commands fail with errno 9 (pg and redis), and pass with the fix. With the sleep moved to index 1, f298af0 logs "ticker faulted: Index was out of range" and the fix does not. * pg-only: the Redis half goes with ioxide.redis (#337)
Merged
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.
Drops
ioxide.redis. It is weight the project does not want to carry: a whole Redis client to maintain, with five open fixes against it, when StackExchange.Redis can run on the reactor's ring instead - #335,ioxide.redis.stackexchange.Removed
src/clients/ioxide.redis(the package) and its CI pack step.Playground/Clients/Redis, its README row, andEnv.OverrideRedis, which only it used.RedisTestsandRedisHandlers. The Redis suite stays - empty, still in the CI loop with its redis sidecar - for the transport's tests in redis.stackexchange: StackExchange.Redis with its connections on the reactor's ring (experimental) #335.bench/run.shand its row inbench/samples.tsv.docs/learn/redis.htmlanddocs/learn/dev-redis.html, with every link to them (each learn page's menu,how-ioxide-does-h3.html, the overview, and the next-page links from the Postgres pages).Http3/Nghttp3Bufferedsample's comments (pane regenerated).The solution builds, and the Redis suite runs with no tests.
src/ioxide/IRingHost.csstill names Redis among the clients a ring can carry; it is core, and still true with #335.Not in this PR
ioxide.redis0.16.281 and earlier stay published; unlisting or deprecating them there is your call.Program.csand.csprojnext to the lines this removes, so whichever merges second needs a one-line resolution.redis.htmlon ioxide.genhttp.run documentsioxide.redis; it gets replaced once this lands.