Curing Your Event Processing Blues with Reactive Extensions
Curing Your Event Processing Blues with Reactive Extensions (Rx) Bart J. F. De Smet Senior Software Development Engineer Microsoft Corporation
GPS RSS Stock feeds ticker s Social media s t n e U v e I Server management
Filtering Grouping Windowing Sampling Sharing Throttling Merging Joins Recovery Projection Aggregating from quote in stock where quote. Symbol == “MSFT” select quote. Value Timeout
Filtering Grouping Windowing Sampling Sharing Throttling Merging Joins Recovery Projection Aggregating from quote in stock where quote. Symbol == “MSFT” select quote. Value Timeout
observable sequences observers Observable Subscribe Observer
Essential Interfaces namespace System { public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); } public interface IObserver<in T> { void On. Next(T value); void On. Error(Exception error); void On. Completed(); } }
On. Next(42) On. Next(43) On. Next(“Hello”) On. Completed On. Error(error) On. Next On. Error On. Completed
Limitations of. NET Events exchange. Stock. Tick += (sender, args) => { if (args. Quote. Symbol == “MSFT”) { // Imperative code } }; exchange. Stock. Tick -= /* what goes here? */;
Observable Sequences to the Rescue IObservable<Quote> stock. Quotes = …; var msft = stock. Quotes. Where(quote => quote. Symbol == “MSFT”); var subscription = msft. Subscribe(quote => /* … */); subscription. Dispose();
. NET Events Observables Code centric Data centric Design-time experience No design-time experience Not first class First class objects Non-compositional Rich composition Lightweight Slightly more cost Rigid execution model (IL) Translatable with expression trees
demo Events versus Observables Bart J. F. De Smet Senior Software Development Engineer Cloud Programmability Team
Filtering Grouping Windowing Sampling Sharing Throttling Merging Joins Recovery Projection Aggregating from quote in stock where quote. Symbol == “MSFT” select quote. Value Timeout
Asynchronous request React Dictionary web service Reaction Reactive Reactor Data binding on UI thread
Converting Events and Asynchronous Methods // Convert the Text. Changed event to IObservable<string> var input = (from evt in Observable. From. Event. Pattern(txt, “Text. Changed”) select ((Text. Box)evt. Sender). Text). Throttle(Time. Span. From. Seconds(0. 5)). Distinct. Until. Changed(); // Convert asynchronous proxy methods to Func<string, IObservable<string[]>> var lookup = Observable. From. Async. Pattern<string, string[]>(svc. Begin. Lookup, svc. End. Lookup); // Compose both sources using a query var res = from term in input from words in lookup(term). Take. Until(input) select words;
demo Querying Event Streams Bart J. F. De Smet Senior Software Development Engineer Cloud Programmability Team
MSFT 27. 01 INTC 21. 75 from tick in ticks MSFT 27. 96 MSFT 31. 21 INTC 22. 54 INTC 20. 98 MSFT 30. 73
MSFT 27. 01 INTC 21. 75 MSFT 27. 96 27. 01 MSFT 31. 21 27. 96 21. 75 from tick in ticks group tick by tick. Symbol INTC 22. 54 INTC 20. 98 MSFT 30. 73 31. 21 22. 54 20. 98
MSFT 27. 01 INTC 21. 75 MSFT 27. 96 [27. 01, 27. 96] MSFT 31. 21 INTC 22. 54 INTC 20. 98 [27. 96, 31. 21] [31. 21, 30. 73] [21. 75, 22. 54] from tick in ticks group tick by tick. Symbol into company from open. Close in company. Buffer(2, 1) MSFT 30. 73 [22. 54, 20. 98]
MSFT 27. 01 INTC 21. 75 MSFT 27. 96 MSFT 31. 21 0. 034 0. 104 INTC 22. 54 INTC 20. 98 MSFT 30. 73 -0. 015 0. 036 -0. 069 from tick in ticks group tick by tick. Symbol into company from open. Close in company. Buffer(2, 1) let diff = (open. Close[1] – open. Close[0]) / open. Close[0]
MSFT 27. 01 INTC 21. 75 MSFT 27. 96 MSFT 31. 21 0. 034 0. 104 INTC 22. 54 where diff > 0. 1 MSFT 30. 73 -0. 015 0. 036 from tick in ticks group tick by tick. Symbol into company from open. Close in company. Buffer(2, 1) let diff = (open. Close[1] – open. Close[0]) / open. Close[0] INTC 20. 98 -0. 069
MSFT 27. 01 INTC 21. 75 MSFT 27. 96 MSFT 31. 21 INTC 22. 54 Company = MSFT Increase = 0. 104 from tick in ticks group tick by tick. Symbol into company from open. Close in company. Buffer(2, 1) let diff = (open. Close[1] – open. Close[0]) / open. Close[0] where diff > 0. 1 select new { Company = company. Key, Increase = diff } INTC 20. 98 MSFT 30. 73
demo Complex Event Processing Bart J. F. De Smet Senior Software Development Engineer Cloud Programmability Team
Filtering Grouping Windowing Sampling Sharing Throttling Merging Joins Recovery Projection Aggregating from quote in stock where quote. Symbol == “MSFT” select quote. Value Timeout
// // Runs a timer on the default scheduler // IObservable long Time. Span // // Every operator that introduces concurrency // has an overload with an IScheduler // IObservable long Time. Span IScheduler scheduler
var Observable. Return Scheduler. Thread. Pool "Answer = " xs. Observe. On( frm ) xs. Observe. On(new Control. Scheduler(frm)). Subscribe(x => lbl. Text = "Answer = " + x);
The IScheduler Interface public interface IScheduler { Date. Time. Offset Now { get; } IDisposable Schedule<TState>( TState state, Func<IScheduler, TState, IDisposable> action); IDisposable Schedule<TState>( Time. Span due. Time, TState state, Func<IScheduler, TState, IDisposable> action); IDisposable Schedule<TState>( Date. Time. Offset due. Time, TState state, Func<IScheduler, TState, IDisposable> action); }
Operational Layering of Rx public static IObservable<T> Return<T>(T value, IScheduler scheduler) { return Observable. Create<T>(observer => { // Serialize state to scheduler; return ability to cancel return scheduler. Schedule(new { value, observer }, (_, x) => { x. observer. On. Next(x. value); x. observer. On. Completed(); return Disposable. Empty; // No recursive work }); }
Virtualizing Time for Testing var scheduler = new Test. Scheduler(); var input = scheduler. Create. Hot. Observable( On. Next(300, “Bart De Smet”), On. Next(400, “Erik Meijer”), On. Completed<string>(500) ); var results = scheduler. Start(() => from name in input select name. Length); results. Messages. Assert. Equal( On. Next(300, 12), On. Next(400, 11), On. Completed<int>(500) );
demo Testing in Virtual Time Bart J. F. De Smet Senior Software Development Engineer Cloud Programmability Team
Runtime translation WMI Events Power. Shell Twitter
The IQbservable<T> Interface public interface IQbservable<out T> : IObservable<T> { Type Element. Type { get; } Expression { get; } IQbservable. Provider { get; } } public interface IQbservable. Provider { IQbservable<T> Create. Query<T>(Expression expression); }
Query language translation IQueryable<T> IQbservable<T> Expression trees Local execution (in-process IL) LINQ IEnumerable<T> Iterators (yield) Pull-based IObservable<T> Observable. Create Push-based
demo LINQ to WMI Events Bart J. F. De Smet Senior Software Development Engineer Cloud Programmability Team
announcing Stream. Insight v 2. 1 Now with support for hosting Rx v 1. 0 queries using IQbservable<T>
Synergy with asynchronous programming features Await support new platform capabilities
Multiple values (*) Single value (1) IEnumerable<T> IObservable<T> var res = from p in products where p. Name == “Rx” select p. Price; var res = from s in stocks where s. Symbol == “MSFT” select q. Quote foreach (var x in res) … res. Subscribe(x => … Func<T> var y = f(x); var z = g(y); Synchronous Task<T> var y = await f. Async(x); var z = await g. Async(y); Asynchronous
Async without Rx… async Task<string> Get. Html. Async(Uri url) { var client = new Web. Client(); var download = client. Download. String. Async(url); var timeout = Task. Delay(Time. Span. From. Seconds(30)); if (await Task. When. Any(download, timeout) == timeout) throw new Timeout. Exception(); var html = await download; return html; }
Async with Rx… Better together! async Task<string> Get. Html. Async(Uri url) { var client = new Web. Client(); var download = client. Download. String. Async(url). To. Observable(). Timeout(Time. Span. From. Seconds(30)); var html = await download; return html; }
Win. RT-style events IScheduler implementations Conversions
System. Reactive. Linq Query operators System. Reactive. Core Base classes, core schedulers, extensions methods System. Reactive. Interfaces Stable interfaces forward compatibility System. Reactive. Platform. Services Platform Enlightenments System. Reactive. Remoting System. Reactive. Windows. Runtime System. Reactive. Windows. Forms System. Reactive. Windows. Threading System. Reactive. Providers Expression tree support
Faster producers Pipeline throughput subjects
demo Preview of Rx v 2. 0 Bart J. F. De Smet Senior Software Development Engineer Cloud Programmability Team
Download http: //www. microsoft. com/download www. nuget. org Rx v 2. 0 RC videos forums http: //channel 9. msdn. com/tags/Rx
DEV 414 – LINQ, Take Two – Realizing the LINQ to Everything Dream Find Me Later This Week In The Ask The Experts Area
Learning Connect. Share. Discuss. Microsoft Certification & Training Resources http: //europe. msteched. com www. microsoft. com/learning Tech. Net Resources for IT Professionals Resources for Developers http: //microsoft. com/technet http: //microsoft. com/msdn
Evaluations Submit your evals online http: //europe. msteched. com/sessions
- Slides: 47