2

Does the .Net Reactive Extensions Framework propagates the notifications in topological order to minimize the amount of updates?

Like Scala Rx does: Does .Net Reactive Extensions (Rx) ta

jeromerg
  • 2,997
  • 2
  • 26
  • 36

2 Answers2

2

.NET Rx uses several semantics while implementing FRP. The key point are the observables and subscriber contexts, especially the schedulers used by subscribers.

TL;DR - .NET RX does not use topological order while invoking notifications.

The long answer: subscibers are invoked by order of their subscription. In a case of concurrency-aware schedulers you could achive parallel invocation using methods ObserveOn/SubscribeOn (more detailed explanation).

Edit (Thanks to @DaveSexton):

Note that neither ObserveOn nor SubscribeOn achieve "parallel" notifications (unless you are comparing segments of the query on both sides of the operator). Note that neither ObserveOn nor SubscribeOn achieve "parallel" notifications (unless you are comparing segments of the query on both sides of the operator). Rx has a strict contract (§4.2) that prevents overlapping (concurrent) notifications within a single subscription, and for hot observables this contract generally applies across subscriptions as well.

szKarlen
  • 66
  • 4
  • Thank you. Would be possible to implement a scheduler that reorders the notifications taking into account the topological order? If yes how difficult would it be? – jeromerg Nov 21 '14 at 15:44
  • @jrg topological order requires rewrite of .NET Rx. Schedulers just take account in execution of notifications, so there is no other way of such kind functionality implementation, I'm afraid. – szKarlen Nov 21 '14 at 15:48
  • Your long answer only takes into account *hot* observables, though in practice it's sometimes true, you cannot necessarily rely on the order of subscriptions. https://social.msdn.microsoft.com/Forums/en-US/ac721f91-4dbc-40b8-a2b2-19f00998239f/order-of-subscriptions-order-of-observations?forum=rx – Dave Sexton Nov 21 '14 at 18:01
  • Note that neither `ObserveOn` nor `SubscribeOn` achieve "parallel" notifications (unless you are comparing segments of the query on both sides of the operator). [Rx has a strict contract](http://go.microsoft.com/fwlink/?LinkID=205219) (§4.2) that prevents overlapping (concurrent) notifications within a single subscription, and for *hot* observables this contract generally applies across subscriptions as well. – Dave Sexton Nov 21 '14 at 18:04
  • @DaveSexton iirc the concurrent notifications requirement was relaxed in later releases. – Cory Nelson Nov 21 '14 at 18:24
  • @DaveSexton thanks for a good point. Edited answer with your comment. – szKarlen Nov 21 '14 at 18:24
  • @CoryNelson No, it's still very much a core principle of Rx! It avoids you having to do things like `.Subscribe(v => { lock (gate) { ... } }); – Dave Sexton Nov 21 '14 at 18:34
  • Note that `Subject` (et. al.), `ObserverBase` and `Observable.Create` do not automatically satisfy the §4.2 contract so you must ensure yourself that you don't call `OnNext` concurrently - unless you don't plan on using any Rx operators. Many Rx operators rely on this contract; if it's not satisfied then you can easily run into strange threading bugs. – Dave Sexton Nov 21 '14 at 18:36
  • Thank you all of you for your replies! Reordering in topological order would introduce a real added value... it would be a kind of feature, that procedural code couldn't compete with! ... Produral code doesn't even have access to the topology of the notification chain ... I will have a look at how difficult it would be to introduce the feature (scala rx as reference example)... please notify, if someone knows a project, that already aims the same purpose! – jeromerg Nov 21 '14 at 19:22
  • @jrg - See `IQbservable` interface. (Note the `Q` is not an `O`) – Dave Sexton Nov 21 '14 at 19:25
  • @DaveSexton 'IQbservable' is out-of-topic. My question focuses on propagation order within the observable-observer subscription graph. Goal is to avoid calling an observer multiple times on a single observable event, for example within a diamond dependency graph. 'IObservable' aims at translating queries for delegating its processing to another machine/query-engine, like a sql-server. – jeromerg Nov 21 '14 at 20:44
  • Unless you're planning on applying notification ordering to a *hot* stateful observable implementation like `Subject` and using that wherever you need it, you're not going to be able to achieve your goal. `IQbservable` makes the entire query graph accessible to you at the time of subscription so that you may dynamically rewrite it to meet your needs; e.g., perhaps by inserting your custom `ISubject`. – Dave Sexton Nov 21 '14 at 21:21
  • 2
    ScalaRx is not RxScala and is not RX. ScalaRx is similar in spirit to Knockout Observables. In ScalaRx, you do not explicitly list your dependencies. You just define your expressions and let the library capture the dependencies for you. Thus it is important for the library to apply some smart reordering of your dependencies. When using Rx (and RxScala), you explicitly define your dependenciy chains and are thus in complete control over the ordering and cardinality of notifications. They are different models and need to be treated as such. – Brandon Nov 22 '14 at 13:50
  • 1
    @Brandon It's worth noting however that the order of subscriptions doesn't necessarily equal the order of observations. In practice it's true for hot observables only (like Subject and FromEvent), and only if you can ensure serialized subscriptions. https://social.msdn.microsoft.com/Forums/en-US/ac721f91-4dbc-40b8-a2b2-19f00998239f/order-of-subscriptions-order-of-observations?forum=rx – Dave Sexton Nov 25 '14 at 12:19
  • @Brandon: ScalaRx people were not forced using a topological order to propagate the push-notifications. They may have chosen to implement a "less-smart" heuristic, like RX's one: i.e. by notifying the observer in the same order as they appear/subscribe to the observables. Are implicit and explicit referencing of dependencies so different from each other? – jeromerg Nov 25 '14 at 19:56
  • @DaveSexton First thank for your contributions and for explaining how `IQbservable` could contribute to reordering! 1) The dependency graph is available with the `IQbservable`, but it is also available as well with `IObservable` 2) Do you mean that cold observables couldn't benefit of a topological reordering? Why? At first sight, I would say that reordering brings benefit as soon as the dependency graph has forks of a single observable that join back farther in the dependency graph, cold or hot. – jeromerg Nov 25 '14 at 20:18
  • 1
    @jrg 1) It's not available with `IObservable`. It's only available in `ISubject` and *hot* observables in general because they broadcast. `IQbservable` (with a `Q`) has the entire graph as an expression tree, regardless of temperature. 2) No, I mean that it's not possible with a *cold* `IObservable` (with an `O`) and it already happens in practice for *hot* observables. See my blog post: http://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx – Dave Sexton Nov 25 '14 at 20:39
1

Storm.Net (Simple Topologically Ordered Reactive Model) his an attempt to provide a data model that propagates update in a topological order.

Orace
  • 7,822
  • 30
  • 45