nats-io/nats.net

Consider using BoundedChannel instead of SemaphoreSlim

Opened this issue · 1 comments

mtmk commented

It is also useful and simplifies a lot just to use a BoundedChannel instead of SemaphoreSlim to synchronize writes to the PipeWriter, since SemaphoreSlim, despite it's name, is not really a lightweight synchronization primitive considering it's pretty likely the writes might be happening from multiple threads for a highly concurrent application. Channels also have some nice optimizations for multiple-writers/single-reader scenarios.

That should simplify the CommandWriter code quite a bit, and connection exceptions can be bubbled up in the WriteLoop by completing the ChannelWriter with an exception for example.

With the Channel, you can also in many/most cases avoid the async state machine when the Channel isn't full, by doing a TryWrite and only falling down to WriteAsync when that fails (the bounded channel is full and waiting for the Write loop to pull stuff off it first). That makes PublishAsync very cheap for the cases where the Pipeline buffer can keep up with the channel ingress.

Originally posted by @stebet in #303 (comment)

see also #303 (comment) by @to11mtm

despite it's name, is not really a lightweight synchronization primitive considering it's pretty likely the writes might be happening from multiple threads for a highly concurrent application.

I should be clear that this statement, I agree in the context of 'lots of WaitAsync calls, for Sync waits it is fine (ish).

However IIRC channel has a little better weak ordering FWIW.

As for how to potentially use a channel, In the past I have used something like this or changed to suit needs appropriately (i.e. if you need a little bit of state).