Observables Reactive Libs Review ObservableDesign Pattern Observables Streams
Observables Reactive Libs Review Observable/Design Pattern Observables Streams Java. Rx Demo Scala. Rx. Shell Demo
Rx. Libs Microsoft open source https: //rx. codeplex. com/ Open source implementations of Reactive. X: https: //github. com/Reactive. X/Rx. Java https: //github. com/Reactive. X/Rx. Scala Netflix open source: http: //techblog. netflix. com/2013/02/rxjava-netflixapi. html Additions on Reactive. X, competition to akka
Observable/Observer not reactive Java Design pattern. Not useful for async or distributed systems. Pre 2000. package com. example; import java. util. Observable; import java. util. Observer; //models customer going to coffeeshop. can change name. leave observer public class My. Observer implements Observer{ private String name=null; private boolean at. Coffee. Shop=false; My. Observer(String n){ this. name=n; } @Override public void update(Observable o, Object arg) { // TODO Auto-generated method stub System. out. println("calling update callback for: "+name); }
Observable package com. example; import java. util. Observable; public class Coffee. Shop extends Observable{ public void enter. Coffee. Shop(My. Observer obs){ add. Observer(obs); } public void notify. Customers(){ set. Changed(); notify. Observers(); } }
Main. java package com. example; public class Main{ public static void main(String []args){ Coffee. Shop cs = new Coffee. Shop(); cs. add. Observer(new My. Observer("cust 1")); cs. add. Observer(new My. Observer("cust 2")); cs. add. Observer(new My. Observer("cust 3")); cs. notify. Customers(); } } Output: calling update callback for: cust 3 calling update callback for: cust 2 calling update callback for: cust 1
Run instr: Download zip: https: //github. com/dougc 333/Test. Code Unarchive, cd Test. Codemaster/Test. Observable, mvn compile $ mvn exec: java Dexec. main. Class=com. example. Main [WARNING] Warning: kill. After is now deprecated. Do you need it ? Please comment on MEXEC-6. calling update callback for: cust 3 calling update callback for: cust 2 calling update callback for: cust 1
Rx. Java NOT ASYNC the Coffeeshop/Observable notifies all the observers via callback function. Java. Rx, Java. Rx. Scala add to this design pattern for event streams and to make async programming possible. Event. Streams=Subscriptions Async: Try/on. Next, on. Complete No Locks, Threads, etc. . . abstracted away Note: code style cleaner than Observer/Observable. Everything in subscription class. No separate driver program needed http: //docs. couchbase. com/prebuilt/java-sdk-2. 0 -beta/topics/observables. html
Rx. Java Create an observerable stream using. just(1, 2, 3) Add a subscriber(lazy eval), similar to observer but add the duality of iterables. Iterable/Observer stream programming. Iterables block/bad perf. Java. Rx adds threads + async on. Next <-> next() on. Complete ↔ has. Next() on. Error ↔ throws exception
Rx. Java Create stream, print package com. example; import rx. Observable; public class Test. Observable{ public static void main(String []args){ System. out. println("asdf"); Observable. just(5, 6, 7, 8). subscribe(new My. Subscriber<Integer>()); //endless stream //Observable. just(5, 6, 7, 8). repeat(). subscribe(new My. Subscriber<Integer>()); } }
Subscriber import rx. Subscriber; class My. Subscriber<Integer> extends Subscriber<Integer>{ @Override public void on. Completed() { // TODO Auto-generated method stub System. out. println("on. Completed"); } @Override public void on. Error(Throwable throwable) { // TODO Auto-generated method stub System. err. println(Error: " + throwable. get. Message()); } @Override public void on. Next(Object arg 0) { // TODO Auto-generated method stub System. out. println("on. Next: " + arg 0); } }
Run instr: cd Test. Observable/Test. Java. Rx mvn clean; mvn compile $ mvn exec: java Dexec. main. Class=com. example. Test. Observabl e [WARNING] Warning: kill. After is now deprecated. Do you need it ? Please comment on MEXEC-6. on. Next: 5 on. Next: 6 on. Next: 7 on. Next: 8 on. Complete
Rx. Java Create static <T> Observable<T> create(Observable. On. Subscribe<T> f) Returns an Observable that will execute the specified function when a Subscriber subscribes to it.
Create a separate class package com. example; import rx. *; //implement logic when to call on. Next(), on. Error(), on. Complete() by using create() //demo only public class Create. Observable<Integer> implements Observable. On. Subscribe<Integer>{ @Override public void call(Subscriber<? super Integer> arg 0) { // TODO Auto-generated method stub Subscriber subscriber = (Subscriber) arg 0; try{ if(!subscriber. is. Unsubscribed()){ for(int i=0; i<5; i++){ subscriber. on. Next(i); } subscriber. on. Completed(); } }catch(Exception e){ subscriber. on. Error(e); } } }
Add subscribe. No drivers!!! package com. example; import rx. *; import rx. functions. Action 1; public class Observable. Create { public static void main(String args[]){ Observable. create(new Create. Observable<Integer>()). subscribe(new Action 1<Integer>() { @Override public void call(Integer integer) { System. out. println("on. Next: " + integer); } }
Run Instr: Run from eclipse
Run from eclipse Run function Action 1 everytime subscriber subscribes. Lazy eval, have to call subscribe to start data processing
Rx. Java API Example Some things are easier in Rx. Java, create a counter once per second. No locks, no threads. Errors and cancellation(unsubscribe) built into the API. Less custom code and less testing.
Timer. java package com. example; import rx. *; import rx. functions. Action 1; import java. util. concurrent. *; public class Timer { static Count. Down. Latch latch = new Count. Down. Latch(5); public static void main(String args[]) throws Interrupted. Exception{ Observable. interval(1, Time. Unit. SECONDS). subscribe(new Action 1<Long>(){ public void call(Long counter){ latch. count. Down(); System. out. println("Timer Secs: "+counter); } }); latch. await(); } }
Run Inst; Run in eclipse
Rx. Java Map Java 7 Uses functions to replace the x=>f(x) notation Modify the timer example to use a map to print out the thread it is operating on Use the testing code. The countdown latch for interval sequences when another thread creates the sequence. Interval is threaded, see scheduler operator table: https: //github. com/Reactive. X/Rx. Java/wiki/ Scheduler#using-schedulers
Timer threads The observable does the work in one thread and the results via the subscriber are displayed in another thread. class Rx. Thread[T](o: Observable[T]) { def exec. Async[T] = { o. subscribe. On(Schedulers. new. Thread). observe. On(Android. Schedulers. main. Thread()). materialize } } /** * Convert implicitly a Java Observable in a Scala Observable. */ object Rx. Thread { implicit def Observable 2 Notification[T](o: Observable[T]) = new Rx. Thread(o) }
Add func public static void debug. Timer() throws Interrupted. Exception{ Observable. interval(1, Time. Unit. SECONDS). map(new Func 1<Long, Long>(){ @Override public Long call(Long i){ System. out. println(Thread. current. Thread(). get. Name()); return i; } }). subscribe(new Action 1<Long>(){ public void call(Long counter){ latch. count. Down(); System. out. println("Timer Secs: "+counter); } }); latch. await(); }
How about a sequence? public static void debug. Seq() { Observable. just(1, 2, 3, 4, 5). map(new Func 1<Integer, Integer>(){ @Override public Integer call(Integer i){ System. out. println(Thread. current. Thread(). get. Name()); return i; } }). subscribe(new Action 1<Integer>(){ @Override public void call(Integer i){ System. out. println("on. Next: " + i); } }); }
Run inst; Comment out either debug. Timer() or debug. Seq() , run Timer. java in Eclipse or maven
Rx. Java Twitter Ex. Building APIs http: //java. dzone. com/articles/turning-twitter 4 jrxjavas Turning Twitter 4 J into Observable. Creates API for stream processing/multiuser nonblocking. Goal: API for user, rolling count of tweets
Making Rx. Java Async and Parallel Trick from lecture: if the return type is <T> this is blocking. If Observable<T> or Future<T> then this is async. Look at Blocking. Observable return types. Marble diagram=>parallel
Marble=>parallelism
Java. Rx parallel Java. Rx controls thread pools using schedulers as describe in lecture when EM compared Execution. Context from Promises/Futures to Observables. Just using flat. Map doesn't guarantee multiple threads. A flat. Map returns Observable<T> which is the first criteria for parallelism
Schedulers add parallelism Debug: Thread. get. Current. Thread(). get. Name(), get. Count() Debug threads in Java. Rx/Java adding to map() using Func 1 Debug in Rx/Scala adding. debug() to package. scala http: //www. grahamlea. com/2014/07/rxjavathreading-examples/
Multiple ways to add threads Docs not clear, look at the Java. Rx test code Test code does this: Creating your own threads In the observable call? On. Next()? Blog does this: Using the thread pool from the scheduler Add spark executors or create your own executor framework using zookeeper(TBD)
Rx/Scala wrapper around a Rx. Java https: //github. com/Reactive. X/Rx. Scala REPL for Observables Not avail from websearch Change $TOOL_PATH under $SCALA_HOME/bin or copy the jars from suggestions/lib_managed/com. netflix. rxjava and rxjava-scala into $SCALA_HOME/lib dir.
Java. Rx The APIs are different between Java. Rx/Java. Rx. Scala/Java. Rx. NET From lecture: Create a stream, notify subscribers on change to represent processing, schedulers manage thread pools vs. Execution. Context in Futures, apply ops to streams which return Observables
Repl lib path
Scala REPL bug scala> import rx. lang. scala. _ scala> val ob = Observable(1, 2, 3, 4) java. lang. No. Such. Method. Error: scala. collection. Java. Converters$. as. Java. Iterable Converter(Lscala/collection/Iterable; )Lscala/coll ection/convert/Decorators$As. Java; at rx. lang. scala. Observable$. apply(Observable. sc ala: 1924)
Upgrade to latest scala version; 2. 11. 2; 2 I/Fs, Rx. Scala scala> import rx. lang. scala. _ scala> val ob = Observable(1, 2, 3, 4) ob: rx. lang. scala. Observable[Int] = rx. lang. scala. Observable$$anon$9@750 cdd 5 e scala>
Importing the wrong lib, Rx. Java scala> import rx. _ scala> val foo = Observable. just(1, 2, 3, 4) foo: rx. Observable[(Int, Int)] = rx. Observable@18 a 8422 d scala>
Upgrade to latest scala version; 2. 11. 2 scala> import rx. lang. scala. _ scala> val ob = Observable(1, 2, 3, 4) ob: rx. lang. scala. Observable[Int] = rx. lang. scala. Observable$$anon$9@750 cdd 5 e scala>
Import the netflix jars(no scheduler) Download from maven central, use the. 20. 4 versions not the 0. 15. 0 versions in the hw rxjava-async-util-0. 20. 4. jar rxjava-computation-expressions-0. 20. 4. jar rxjava-core-0. 15. 0. jar rxjava-core-0. 20. 4. jar rxjava-scala-0. 15. 0. jar rxjava-scala-0. 20. 4. jar
Subscribe to the Observable, much easier than Java 7 scala> foo. subscribe(x=>println(x)) 1 2 3 4 res 0: rx. lang. scala. Subscription = rx. lang. scala. subscriptions. Subscription$$anon$ 1@4 f 91659 c
Observables Repeat Rx in Scala Observables require subscribers to send notifications to when data is ready in the Observable. An observable is the dual of an iterator but can return 0 or many events or an Error. Key is the 0 event. Doesn't have to be async An observable interface contains: on. Next on. Error on. Completed
Rx. Scala Homework apply() (for maps, flat. Map) Add what on top of adding subscribers to observables?
Subjects For async programming, a subject is like a promise. A promise contains a future just as a future has to wait for a promise to write the data A subject contains an Observable<T> or Observer<T>?
- Slides: 42