rabbitmq-dotnet-client icon indicating copy to clipboard operation
rabbitmq-dotnet-client copied to clipboard

8.0 Proposal (internal): Use IValueTaskSource for RPC continuations awaits

Open bollhals opened this issue 4 years ago • 4 comments

In order to prepare for the async interface, one part of the whole library is the RpcContinuationQueue. With the current implementation we can not support async waiting on completion. => I propose to use a IValueTaskSource<T> and create a class that handles this.

This way we could set the reply with one method and have another which you could use to wait.

void SetReply(in IncomingCommand cmd)
ValueTask<IncomingCommand> GetReplyAsync()

instead of the current (used my latest branch to experiment)

IncomingCommand GetReply()
void HandleCommand(in IncomingCommand cmd)

With this implementation we can avoid a lot of allocations for an RPC await.

I have a very basic working prototype up and running locally. If the extended functionality (timeout, shutdown) is fully implmented and working, I'll set up a PR for the current sync API with GetReplyAsync().AsTask.GetAwaiter().GetResult(). in every public API. => Async under the hood, so we'd ready to switch.

bollhals avatar Oct 30 '20 00:10 bollhals

I already have a working type in the async branch, which uses/reuses ValueTasks from a pooled resource. You can use that as a reference as well. It also uses locking to guarantee that only one operation is outstanding per model. See here: https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/full-async/projects/RabbitMQ.Client/client/impl/RpcContinuationQueue.cs

stebet avatar Oct 30 '20 08:10 stebet

Moving to 8.0 so that we can ship a 7.0 with a smaller set of breaking API changes if necessary.

michaelklishin avatar Nov 06 '20 15:11 michaelklishin

I believe that the AsyncRpcContinuation class and subclasses effectively implement this suggestion.

lukebakken avatar Dec 29 '23 00:12 lukebakken

I believe that the AsyncRpcContinuation class and subclasses effectively implement this suggestion.

They are TaskCompletionSource based which does allocate where IValueTaskSource doesn't. It's not a huge issue though and something I can look at later.

stebet avatar Jan 03 '24 08:01 stebet