rx 101 codemotion milan 2015 - tamir dresher
TRANSCRIPT
MILAN 20/21.11.2015
Talk title: Reactive Extensions 101Tamir Dresher – CodeValue - @tamir_dresher
• Software Architect, Consultant and Instructor
• Software Engineering Lecturer @ Ruppin Academic Center
@[email protected]://www.TamirDresher.com.
Your headache relief pill to Asynchronous and Event based applications
AsyncPush
TriggersEvents
Reactive Extensions
Reactive Programming concentrates on the propagation of changes and
their effectssimply put, how to react to
changes and create dataflows that depend on
them
Reactive Programming
5
Socialmedia
High Rate Data
IoTGPS
External Services
UI eve
nts
Your System
So Many Sources…
Source/Producer
Target/Consumer
Producer-Consumer
Source/Producer
Target/Consumer
Source/Producer
Source/Producer
Target/Consumer
Target/Consumer
Producer-Consumer
IEnumerable<Message> LoadMessages(string hashtag){
var statuses = facebook.Search(hashtag);var tweets = twitter.Search(hashtag);var updates = linkedin.Search(hashtag);return statuses.Concat(tweets).Concat(updates);
}
Twitter AppLinkedi
n
Pull Model
???? LoadMessages(string hashtag){
facebook.Search(hashtag);twitter.Search(hashtag);linkedin.Search(hashtag);
}
DoSomething( )msg
Push Model
observable observer
Subscribe(observer)
subscription
OnNext(X1)
OnNext(Xn)⁞
X1observable X2 Xn
⁞IDisposable
Observables and Observers
OnCompleted()
OnError(Exception)
observable
observable observer
X1 X2 Xn
⁞
Observables and Observers
namespace System{ public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); }
public interface IObserver<in T> { void OnNext(T value); void OnError(Exception error); void OnCompleted(); }}
Interfaces
MILAN 20/21.11.2015
Creating Observables
IObservable<Message> ObserveMessages(string hashtag){
}
return Observable.Create( async (o) => {
});
var messages = await GetMessagesAsync(hashtag);foreach(var m in messages){ o.OnNext(m);}o.OnCompleted();
Pull To Push
IObservable<Message> ObserveMessages(string hashtag){
}
return Observable.Defer( async () => {
});
var messages = await GetMessagesAsync(hashtag);return message.ToObservable();
Built-in Converters
Observable.Merge(
facebook.ObserveMessages(hashtag),
twitter.ObserveMessages(hashtag),
linkedin.ObserveMessages(hashtag));
Built-in Operators
Observable.Range(1, 10) .Subscribe(x => Console.WriteLine(x));
Observable.Interval(TimeSpan.FromSeconds(1)) .Subscribe(x => Console.WriteLine(x));
Observable.FromEventPattern(SearchBox, "TextChanged")
1 2 10
⁞1 2 10
⁞1 sec 1 sec
Observables Factories
⁞
MILAN 20/21.11.2015
Observable Queries (Rx Operators)
Filtering Projection Partitioning Joins Grouping Set
Element Generation Quantifiers Aggregation Error HandlingTime and Concurrency
Where
OfType
Select
SelectMany
Materialize
Skip
Take
TakeUntil
CombineLatest
Concat
join
GroupBy
GroupByUntil
Buffer
Distinct
DistinctUntilChanged
Timeout
TimeInterval
ElementAt
First
Single
Range
Repeat
Defer
All
Any
Contains
Sum
Average
Scan
Catch
OnErrorResumeNext
Using
Operator2 Creates an IObservable<T3>
IObservable<T2> Operator<T1>(IObservable<T1> source, parameters);
Operator 1 Subscribe( )
observer
observable… Operator
N
Operator1 Creates an IObservable<T2>
IObservable<T>Original source
observerSubscribe
Composability
g(x)
f(x)
Observable Query Pipeline
Reactive Search
1. At least 3 characters2. Don’t overflow server (0.5 sec delay)3. Don’t send the same string again4. Discard results if another search was
requested
Reactive Search - Rules
Demo
Var textChanged = Observable.FromEventPattern(txt,
“TextChanged”).Select(_=>txt.Text);
textChanged.Where(text=>text.Length>3).Throttle(TimeSpan.FromSeconds(0.5)).DistinctUntilChanged().SelectMany(text => SearchAsync(text)).Switch().Subscribe(/*handle the results*/);
var $input = $('#input'), $results = $('#results');
Rx.Observable.fromEvent($input, 'keyup') .map(e => e.target.value) .filter(text => text.length > 3) .throttle(500 /* ms */) .distinctUntilChanged() .flatMapLatest(searchWikipedia) .subscribe(data => { var res = data[1]; $results.empty(); $.each(res, (_, value) => $('<li>' + value + '</li>').appendTo($results)); }, error => { /* handle any errors */ $results.empty(); $('<li>Error: ' + error + '</li>').appendTo($results);});
MILAN 20/21.11.2015
Abstracting Time and Concurrency
Thread Pool
Task Scheduler
other
Schedulers
public interface IScheduler{ DateTimeOffset Now { get; }
IDisposable Schedule<TState>( TState state, Func<IScheduler, TState, IDisposable> action);
IDisposable Schedule<TState>(TimeSpan dueTime, TState state,Func<IScheduler, TState, IDisposable> action);
IDisposable Schedule<TState>(DateTimeOffset dueTime,
TState state,Func<IScheduler, TState, IDisposable> action);
}
//// Runs a timer on the default scheduler//IObservable<T> Throttle<T>(TimeSpan dueTime);
//// Every operator that introduces concurrency// has an overload with an IScheduler//IObservable<T> Throttle<T>(TimeSpan dueTime, IScheduler scheduler);
Parameterizing Concurrency
textChanged
.Throttle(TimeSpan.FromSeconds(0.5),
DefaultScheduler.Instance).DistinctUntilChanged().SelectMany(text =>
SearchAsync(text)).Switch().Subscribe(/*handle the
results*/);
//// runs the observer callbacks on the specified // scheduler.//IObservable<T> ObserveOn<T>(IScheduler);
//// runs the observer subscription and unsubsciption on// the specified scheduler.//IObservable<T> SubscribeOn<T>(IScheduler)
Changing Execution Context
textChanged.Throttle(TimeSpan.FromSeconds(0.5)).DistinctUntilChanged().SelectMany(text =>
SearchAsync(text)).Switch()
.ObserveOn(DispatcherScheduler.Current).Subscribe(/*handle the results*/);
Changing Execution Context
textChanged.Throttle(TimeSpan.FromSeconds(0.5)).DistinctUntilChanged().SelectMany(text =>
SearchAsync(text)).Switch().ObserveOnDispatcher().Subscribe(/*handle the results*/);
Changing Execution Context
http://blogs.msdn.com/b/rxteam/archive/2012/06/14/testing-rx-queries-using-virtual-time-scheduling.aspx
Virtualizing Time
Your headache relief pill to Asynchronous and Event based applications
AsyncPush
TriggersEvents
Reactive Extensions
Thank You
www.manning.com/dresher www.reactivex.io github.com/Reactive-Extensions
Discount code: ctwcodemot
MILAN 20/21.11.2015 - Tamir Dresher – Rx 101
Leave your feedback on Joind.in!https://m.joind.in/event/codemotion-milan-2015
Presenter contact detailst: @tamir_dreshere: [email protected]: TamirDresher.comw: www.codevalue.net