Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Bart De Smet

Bart De Smet bdesmet Bart De Smet ​[MSFT::SQL::​Cloud​Programmabi​lity::Rx]

Niner since 2004

Software Development Engineer at Microsoft Corporation
  • Bart De Smet: Inside Rx 2.0 Beta

    @LeeCampbell: At this point, there are no magic tricks to know whether an operator is part of a "safe" chain. What's really going on here is a different approach to writing operators, based on custom observer implementations rather than the anonymous implementation approach through lambda-based Subscribe calls to the sources of the operator.

    In order to ensure "global" safety, there's a minimal amount of cheap safeguarding based on swapping out observers for mute ones as soon as an operator's input reaches a terminal state. So, multiple terminal messages (invalid from the grammar's point of view) are silenced but the first one, and the place this happens is inside the custom operator noticing this (rather than in the Subscribe method's wrapping of the observer in the past).

    As for concurrent notifications (which are invalid too), there has never been true safeguarding against this, so inputs are assumed to be safe. Only when an operator has to deal with multiple sources, it will do proper orchestration internally (e.g. Merge has to ensure we never talk to the outgoing observer in a concurrent manner), using locks or other approaches. However, when an ill-behaved producer is in the mix, behavior is undefined (e.g. a Subject<T> that exhibits concurrent messages). In case such a producer exists, one has to safeguard the pipeline using Synchronize.

    When implementing sources or custom operators, we recommend to use ObservableBase<T> and Observable.Create, respectively. Those are the safest way to get things right. In fact, for custom operators, the use of composition of existing operators is a good start. Going forward, we may provide more advanced "power user" facilities to write more efficient custom operators using techniques similar to the ones we're using internally now. However, with power comes responsibility, so users of such primitives and implementation patterns need to have a thorough understanding of expectations with regards to observable sequences, the observer grammar, etc.

  • Bart De Smet: Inside Rx 2.0 Beta

    @Kim: The platform enhancements are loaded through a Type.GetType call, followed by an instantiation of the discovered type (if any). The resulting object is cached so subsequent uses of the service don't take a performance hit.

    The BCL/CLR teams are aware of the need for such tricks in some types of APIs, and we may see more guidance or helper functionality to address this going forward (no promises implied in this statement). For a lot of Portable Libraries though, one can live without such mechanisms. Think about class libraries for a data model that can be reused across Windows Phone, Metro, Silverlight, classic desktop, etc.

  • Bart De Smet: Inside Rx 2.0 Beta

    @Maddus Mattus: Still need to allocate the IDisposable. This said, not that big of a deal, especially if you don't ever need to unsubscribe, meaning the object becomes food for a Gen0 collection.

    As soon as you start composing events, the benefits far outweigh the cost. A lot of the composition of Rx builds on the ability to compose subscriptions. Subscribing to the merge of N sources means returning an IDisposable that holds on to the underlying N source subscriptions. It's as simple as that.

    If you'd measure all sorts of performance metrics in real-world scenarios, I doubt the disposable object graph will show up as a relevant influence. (Btw, we have many IDisposable implementations internally in Rx, also to allow for reuse of objects.) It definitely didn't in the Rx v2.0 Beta analysis of performance. Also, typically there's 1 subscription for a whole bunch of events flowing through the pipeline: 1 <<<<< N.

    To conclude, my remark is mostly about the debate whether or not observables are a primitive or an abstraction over a primitive. Just like delegates are first-class representations of methods, observables are first-class representations of events (which are method pairs for our purposes). In this analogy, one doesn't "convert" (e.g. through method group conversion in C#, see ECMA 334, section 13.6) a method into a delegate unless you want to do a more functional style composition (e.g. LINQ to Objects heavily relies on delegates). The same holds for observables, with the only difference being a bit more friction to convert an event to its first-class representation (i.e. there's no method group equivalent for event members).

  • Bart De Smet: Inside Rx 2.0 Beta

    @Novox: You're seeing an internal namespace with a Greek alpha in its name to make the call stack look exactly like the methods you wrote. We can't have inner classes such as Where nested inside Observable, because there's already a method with that name. So, the closest approximation was an Observαble namespace with classes such as Where in it.

    Unfortunately, the namespace shows up in IntelliSense at this point, due to some complexities around the IDE's handling of InternalsVisibleTo. We're aware of this problem and are looking into it.

  • Bart De Smet: Inside Rx 2.0 Beta

    @Maddus Mattus: Observables come at a slightly higher cost than events, e.g. due to the need for an IDisposable "subscription handle". So, having events at the core isn't a bad thing either. For "non-complex event processing" scenarios, a simple event handler often suffices (e.g. the form closing event to pop up a "do you want to save" dialog).

    What you likely want is a smoother way to convert an event into an observable sequence, just like F# has an implicit conversion allowing this (see here and here for starters).

  • Bart De Smet: Inside Rx 2.0 Beta

    @Mike: There are a whole bunch of use cases. I'm surprised to learn about new customers using Rx in different ways every week. Most recently:

    • Data center monitoring scenarios - e.g. computing moving aggregates of CPU utilization, noticing peaks, etc.
    • Sensor and signal processing systems - e.g. collecting and processing data in smart grids, network centers, etc.
    • Robotics where queries over sensor inputs control servos etc. - e.g. we've seen queries being compiled into embedded code.
    • GPS processing systems to tame events of long/lat pairs - e.g. filter out noise, correlate with other data stores, etc.
    • Intrusion detection systems by processing historical logs and real-time data - e.g. logs of requests / IP address, try to find suspicious outliers.
    • Blending UI events with asynchronous requests to web services etc. - e.g. take input in a text box and launch async web calls for completion etc.

    The spectrum of places used has also grown signficantly. We started off by going into Windows Phone 7 as an API to help users process sensor data (accelerometer, GPS, etc.). In full desktop CLR, we've seen adoption ranging from client UI scenarios to server/datacenter workloads. We're seeing an increasing interest in the embedded space as well, including robotics. And we have Rx for JavaScript used in both client and server scenarios (e.g. node.js).

    Stay tuned and you'll see us "eat our own dogfood" in various places. Quite a few products today are shipping "powered by Rx" (most lately PowerView in SQL Server 2012, various online services in Bing, but also yet-unannounced projects), and the number is growing fast.

    With regards to debuggability, we've done a lot of work in this release to make callstacks readable, approachable, and understandable (see the blog post). This is just the end of the beginning of work we're doing in this field. So again, stay tuned!

  • Bart De Smet: Rx Update - .NET 4.5, Async, WinRT

    @ninjeff: One thing that would help is to have Task implement IObservable. Given that any multi-value concept has the single-value case covered too, that'd be a good way to think about it. However, in the synchronous case, there's no such implicit conversion between a multi-value thing (e.g. an array) that happens to have a single value and its contents (an "unpack" operation). Rest assure we are (and will continue to be) thinking about co-evolution and co-existence...

  • Bart De Smet: Rx Update - .NET 4.5, Async, WinRT

    @ligAZ: We're actively working with the PLIB folks on making Rx portable. The main thing required is to have IObservable available in all supported platforms. At this point, we can't commit to a time frame, but we're on it Smiley.

  • Bart De Smet: Rx Update - .NET 4.5, Async, WinRT

    @AdamSpeight2008: Remains to be seen. Notice the trend of reducing magic strings in pretty much every recent release of the languages (e.g. LINQ instead of queries in strings, dynamic instead of invocation calls with member names in strings, call info attributes instead of hardcoding the current member's name, etc.).

    Personally, to reduce the event conversion friction I'd invest in a conversion of events to IObservable<T> like F# does, but at this point there are no such plans.

  • Bart De Smet: Rx Update - .NET 4.5, Async, WinRT

    @felix9: The test code you saw on the screen is not flawless indeed. In general, it's possible for the sequence to produce an OnNext message before the Dispose call to the subscription occurs. The fix is quite simple though: use the Finally operator in Rx to run code after the sequence completes or gets disposed.

See more comments…