1 / 42

Observables

Reactive Libs Review Observable/Design Pattern Observables Streams JavaRx Demo ScalaRxShell Demo. Observables. RxLibs. Microsoft open source https://rx.codeplex.com/ Open source implementations of ReactiveX: https://github.com/ReactiveX/RxJava https://github.com/ReactiveX/RxScala

Download Presentation

Observables

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Reactive Libs Review Observable/Design Pattern Observables Streams JavaRx Demo ScalaRxShell Demo Observables

  2. RxLibs • Microsoft open source • https://rx.codeplex.com/ • Open source implementations of ReactiveX: • https://github.com/ReactiveX/RxJava • https://github.com/ReactiveX/RxScala • Netflix open source: • http://techblog.netflix.com/2013/02/rxjava-netflix-api.html • Additions on ReactiveX, competition to akka

  3. 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 MyObserver implements Observer{ private String name=null; private boolean atCoffeeShop=false; MyObserver(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); } }

  4. Observable • package com.example; • import java.util.Observable; • public class CoffeeShop extends Observable{ • public void enterCoffeeShop(MyObserver obs){ • addObserver(obs); • } • public void notifyCustomers(){ • setChanged(); • notifyObservers(); • } • }

  5. Main.java • package com.example; • public class Main{ • public static void main(String []args){ • CoffeeShop cs = new CoffeeShop(); • cs.addObserver(new MyObserver("cust1")); • cs.addObserver(new MyObserver("cust2")); • cs.addObserver(new MyObserver("cust3")); • cs.notifyCustomers(); • } • } • Output: • calling update callback for:cust3 • calling update callback for:cust2 • calling update callback for:cust1

  6. Run instr: • Download zip: https://github.com/dougc333/TestCode • Unarchive, cd TestCode-master/TestObservable, mvn compile • $ mvn exec:java -Dexec.mainClass=com.example.Main • [WARNING] Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6. • calling update callback for:cust3 • calling update callback for:cust2 • calling update callback for:cust1

  7. RxJava • NOT ASYNC • the Coffeeshop/Observable notifies all the observers via callback function. JavaRx, JavaRxScala add to this design pattern for event streams and to make async programming possible. • EventStreams=Subscriptions • Async: Try/onNext,onComplete • 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

  8. RxJava • 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. JavaRx adds threads + async • onNext <-> next() • onComplete ↔ hasNext() • onError ↔ throws exception

  9. RxJava Create stream, print • package com.example; • import rx.Observable; • public class TestObservable{ • public static void main(String []args){ • System.out.println("asdf"); • Observable.just(5,6,7,8).subscribe(new MySubscriber<Integer>()); • //endless stream • //Observable.just(5,6,7,8).repeat().subscribe(new MySubscriber<Integer>()); • } • }

  10. Subscriber • import rx.Subscriber; • class MySubscriber<Integer> extends Subscriber<Integer>{ • @Override • public void onCompleted() { • // TODO Auto-generated method stub • System.out.println("onCompleted"); • } • @Override • public void onError(Throwable throwable) { • // TODO Auto-generated method stub • System.err.println(Error: " + throwable.getMessage()); • } • @Override • public void onNext(Object arg0) { • // TODO Auto-generated method stub • System.out.println("onNext: " + arg0); • } • }

  11. Run instr: • cd TestObservable/TestJavaRx • mvn clean;mvn compile • $ mvn exec:java -Dexec.mainClass=com.example.TestObservable [WARNING] Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6. onNext: 5 onNext: 6 onNext: 7 onNext: 8 onComplete

  12. RxJava Create • static <T> Observable<T> create(Observable.OnSubscribe<T> f) • Returns an Observable that will execute the specified function when a Subscriber subscribes to it.

  13. Create a separate class • package com.example; • import rx.*; • //implement logic when to call onNext(), onError(), onComplete() by using create() • //demo only • public class CreateObservable<Integer> implements Observable.OnSubscribe<Integer>{ • @Override • public void call(Subscriber<? super Integer> arg0) { • // TODO Auto-generated method stub • Subscriber subscriber = (Subscriber) arg0; • try{ • if(!subscriber.isUnsubscribed()){ • for(int i=0;i<5; i++){ • subscriber.onNext(i); • } • subscriber.onCompleted(); • } • }catch(Exception e){ • subscriber.onError(e); • } • } • }

  14. Add subscribe. No drivers!!! • package com.example; • import rx.*; • import rx.functions.Action1; • public class ObservableCreate { • public static void main(String args[]){ • Observable.create(new CreateObservable<Integer>()).subscribe(new Action1<Integer>() { • @Override • public void call(Integer integer) { • System.out.println("onNext: " + integer); • } • }); • } • }

  15. Run Instr: • Run from eclipse

  16. Run from eclipse • Run function Action1 everytime subscriber subscribes. Lazy eval, have to call subscribe to start data processing

  17. RxJava API Example • Some things are easier in RxJava, create a counter once per second. No locks, no threads. Errors and cancellation(unsubscribe) built into the API. Less custom code and less testing.

  18. Timer.java • package com.example; • import rx.*; • import rx.functions.Action1; • import java.util.concurrent.*; • public class Timer { • static CountDownLatch latch = new CountDownLatch(5); • public static void main(String args[]) throws InterruptedException{ • Observable.interval(1,TimeUnit.SECONDS).subscribe(new Action1<Long>(){ • public void call(Long counter){ • latch.countDown(); • System.out.println("Timer Secs:"+counter); • } • }); • latch.await(); • } • }

  19. Run Inst; • Run in eclipse

  20. RxJava Map Java7 • 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/ReactiveX/RxJava/wiki/Scheduler#using-schedulers

  21. Timer threads • The observable does the work in one thread and the results via the subscriber are displayed in another thread. class RxThread[T](o:Observable[T]) { def execAsync[T] = { o.subscribeOn(Schedulers.newThread) .observeOn(AndroidSchedulers.mainThread()) .materialize } } /** * Convert implicitly a Java Observable in a Scala Observable. */ object RxThread { implicit def Observable2Notification[T](o: Observable[T]) = new RxThread(o) }

  22. Add func • publicstaticvoid debugTimer() throws InterruptedException{ • Observable.interval(1,TimeUnit.SECONDS).map(new Func1<Long,Long>(){ • @Override • public Long call(Long i){ • System.out.println(Thread.currentThread().getName()); • return i; • } • }).subscribe(new Action1<Long>(){ • publicvoid call(Long counter){ • latch.countDown(); • System.out.println("Timer Secs:"+counter); • } • }); • latch.await(); • }

  23. How about a sequence? • publicstaticvoid debugSeq() { • Observable.just(1,2,3,4,5).map(new Func1<Integer,Integer>(){ • @Override • public Integer call(Integer i){ • System.out.println(Thread.currentThread().getName()); • return i; • } • }).subscribe(new Action1<Integer>(){ • @Override • publicvoid call(Integer i){ • System.out.println("onNext: " + i); • } • }); • }

  24. Run inst; • Comment out either debugTimer() or debugSeq() , run Timer.java in Eclipse or maven

  25. RxJava Twitter Ex. Building APIs • http://java.dzone.com/articles/turning-twitter4j-rxjavas • Turning Twitter4J into Observable. Creates API for stream processing/multiuser nonblocking. • Goal: API for user, rolling count of tweets

  26. Making RxJava 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 BlockingObservable return types. Marble diagram=>parallel

  27. Marble=>parallelism

  28. JavaRx parallel • JavaRx controls thread pools using schedulers as describe in lecture when EM compared ExecutionContext from Promises/Futures to Observables. • Just using flatMap doesn't guarantee multiple threads. A flatMap returns Observable<T> which is the first criteria for parallelism

  29. Schedulers add parallelism • Debug:Thread.getCurrentThread().getName(), getCount() • Debug threads in JavaRx/Java adding to map() using Func1 • Debug in Rx/Scala adding .debug() to package.scala • http://www.grahamlea.com/2014/07/rxjava-threading-examples/

  30. Multiple ways to add threads • Docs not clear, look at the JavaRx test code • Test code does this: Creating your own threads • In the observable call? • OnNext()? • Blog does this: Using the thread pool from the scheduler • Add spark executors or create your own executor framework using zookeeper(TBD)

  31. Rx/Scala • Scala wrapper around a RxJava • https://github.com/ReactiveX/RxScala • 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.

  32. JavaRx • The APIs are different between JavaRx/JavaRxScala/JavaRxNET • From lecture: • Create a stream, notify subscribers on change to represent processing, • schedulers manage thread pools vs. ExecutionContext in Futures, • apply ops to streams which return Observables

  33. Repl lib path

  34. Scala REPL bug • scala> import rx.lang.scala._ • scala> val ob = Observable(1,2,3,4) • java.lang.NoSuchMethodError: scala.collection.JavaConverters$.asJavaIterableConverter(Lscala/collection/Iterable;)Lscala/collection/convert/Decorators$AsJava; • at rx.lang.scala.Observable$.apply(Observable.scala:1924)

  35. Upgrade to latest scala version; 2.11.2; 2 I/Fs, RxScala • scala> import rx.lang.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@750cdd5e • scala>

  36. Importing the wrong lib, RxJava • scala> import rx._ • import rx._ • scala> val foo = Observable.just(1,2,3,4) • foo: rx.Observable[(Int, Int, Int, Int)] = rx.Observable@18a8422d • scala>

  37. Upgrade to latest scala version; 2.11.2 • scala> import rx.lang.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@750cdd5e • scala>

  38. 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

  39. Subscribe to the Observable, much easier than Java7 • scala> foo.subscribe(x=>println(x)) • 1 • 2 • 3 • 4 • res0: rx.lang.scala.Subscription = rx.lang.scala.subscriptions.Subscription$$anon$1@4f91659c

  40. 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: • onNext • onError • onCompleted

  41. RxScala • Homework • apply() (for maps, flatMap) • Add what on top of adding subscribers to observables?

  42. 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>?

More Related