Discussion required: remove PreserveAsyncOrder by mgravell · Pull Request #877 · StackExchange/StackExchange.Redis (original) (raw)

@NickCraver OK, I had an idea. Let me rubber-duck this against you a sec.

consider: we add two methods onto ChannelMessageQueue:

public void OnMessage(Action<RedisChannel, RedisValue> handler) {...} public void OnMessage(Func<RedisChannel, RedisValue, Task> handler) {...}

These would only work once - if you try to OnMessage a second time it laughs at you. Implementation: exactly as shown above:

while (!queue.IsCompleted) { ChannelMessage next; try { next = await queue.ReadAsync(); } catch (ChannelClosedException) { break; } // an inbuilt

try { handler(next.Channel, next.Value); }
catch (Exception anythingElse) { ...log?...}

}

(we'd probably kick off the initial exec on the TP, since Channel<T> loves TP)

and for the async case:

try { await handler(next.Channel, next.Value) ?? Task.CompletedTask; }

Another more ambitious option:

I think that now that the machinery is in place, I could actually use this to reinstate PreserveAsyncOrder, but with a slightly different meaning:

We could also consider whether it makes sense to request this mode on a per-subscription basis (presumably via CommandFlags), but that's separate.

Basically, the idea is: if PreserveAsyncOrder is enabled (whether globally or per-subscription, implementation detail), we spin up a ChannelMessageQueue without showing the user, and call OnMessage with their handler.

This would, IMO, allow a much easier transition for many users, but I wonder if it propagates bad habits.


Thoughts?