Reactive: When will AsyncRx.NET release?

Created on 30 Dec 2019  路  5Comments  路  Source: dotnet/reactive

question [area] Rx

Most helpful comment

Closing this in favor of the issue tracking the production of a preview package in NuGet. Note the word preview; things may and will change.

The history of async Rx predates C# 8.0's IAsyncEnumerable<T> (as does Ix's initial variant of IAsyncEnumerable<T> all the way back in 2014) and is in fact a by-product of an internal effort to build a distributed event processing system (code-named "Reactor") which for various reasons has not yet found its way to OSS. The initial implementation here has been a science project to bring out the most valuable and directly applicable bit of said "Reactor" service, namely an operator library, without a lot of strings attached (a "fresh" implementation if you will), and while trying to get a sense for interest in such a library.

Where the "Reactor" service had to deal with a lot of orthogonal concerns around state persistence (checkpointing), message reliability (across compute nodes that may fail over), serialization of events and state, distribution of compute, etc., this library picked one of the main differentiators, being the asynchronous bit. The asynchrony naturally emerged in "Reactor" from sending events across clients and services, between services, and between compute nodes within a service, thus resulting in an IAsyncObserver<T> interface (as well as async subscription and disposal, across boundaries), thus forcing the query engine implementation sandwiched in between receiving events and sending events (thus "processing" events) to have some form of asynchrony. Some implementations achieved this by intermediate buffering of events or conversions to synchronous interfaces (to bind to a variant of Rx with checkpointing support), while others had yet another reason to get asynchrony in the core of the event processing system, namely evaluation of async query clauses (e.g weatherAlerts.Select(async w => await Translate(w.Alert, "EN", "NL"))). The latter is where asynchrony becomes inevitable all the way throughout the stack.

Anyway, the project here has taken some shape and is now converging to the new kids on the .NET blocks such as IAsyncDisposable and ValueTask. Part of stalling the process here was to avoid introducing conflicts between System.* types added here and now added in .NET proper. Further things to consider are a re-evaluation of the duality with IAsyncEnumerable<T> now that those interfaces are stable. A particularly interesting bit is the (pragmatic) decision around a single CancellationToken for an entire enumeration versus fine-grained cancellation of MoveNextAsync calls. The "Reactor" variant was slightly different in nature with fine-grained cancellation for all On*Async calls, because we're often dealing with a cross-machine boundary when sending messages, and said I/O can be cancelled. The initial implementation here intentionally steered away from making decisions around cancellation support while the design work on IAsyncEnumerable<T> was taking place (and the async variant of Ix, now called System.Linq.Async, was being altered numerous times as the interfaces changed).

All 5 comments

We don't know as there hasn't been much development around it lately, or some documentation for devs. Besides, I find it too convoluted and I feel uncomfortable supporting it at this point in time. I recommend AsyncEnumerables instead.

Are there any updates on subject? AsyncEnumerable can't completely replace AsyncObservable and vice versa.

then why put it 's source code there, even no initial preview release for such a long time, how many developers here from MS allocated? Is Microsoft treat RX seriously? At least for me, AsyncRX's source code is much clearer than current Rx implementation.

See #1248.

Closing this in favor of the issue tracking the production of a preview package in NuGet. Note the word preview; things may and will change.

The history of async Rx predates C# 8.0's IAsyncEnumerable<T> (as does Ix's initial variant of IAsyncEnumerable<T> all the way back in 2014) and is in fact a by-product of an internal effort to build a distributed event processing system (code-named "Reactor") which for various reasons has not yet found its way to OSS. The initial implementation here has been a science project to bring out the most valuable and directly applicable bit of said "Reactor" service, namely an operator library, without a lot of strings attached (a "fresh" implementation if you will), and while trying to get a sense for interest in such a library.

Where the "Reactor" service had to deal with a lot of orthogonal concerns around state persistence (checkpointing), message reliability (across compute nodes that may fail over), serialization of events and state, distribution of compute, etc., this library picked one of the main differentiators, being the asynchronous bit. The asynchrony naturally emerged in "Reactor" from sending events across clients and services, between services, and between compute nodes within a service, thus resulting in an IAsyncObserver<T> interface (as well as async subscription and disposal, across boundaries), thus forcing the query engine implementation sandwiched in between receiving events and sending events (thus "processing" events) to have some form of asynchrony. Some implementations achieved this by intermediate buffering of events or conversions to synchronous interfaces (to bind to a variant of Rx with checkpointing support), while others had yet another reason to get asynchrony in the core of the event processing system, namely evaluation of async query clauses (e.g weatherAlerts.Select(async w => await Translate(w.Alert, "EN", "NL"))). The latter is where asynchrony becomes inevitable all the way throughout the stack.

Anyway, the project here has taken some shape and is now converging to the new kids on the .NET blocks such as IAsyncDisposable and ValueTask. Part of stalling the process here was to avoid introducing conflicts between System.* types added here and now added in .NET proper. Further things to consider are a re-evaluation of the duality with IAsyncEnumerable<T> now that those interfaces are stable. A particularly interesting bit is the (pragmatic) decision around a single CancellationToken for an entire enumeration versus fine-grained cancellation of MoveNextAsync calls. The "Reactor" variant was slightly different in nature with fine-grained cancellation for all On*Async calls, because we're often dealing with a cross-machine boundary when sending messages, and said I/O can be cancelled. The initial implementation here intentionally steered away from making decisions around cancellation support while the design work on IAsyncEnumerable<T> was taking place (and the async variant of Ix, now called System.Linq.Async, was being altered numerous times as the interfaces changed).

Was this page helpful?
0 / 5 - 0 ratings