JVM Reactive Programming
Mexico City JVM Group
October 2016
domix
domix
coderDog
!Gracias por estar aqui¡
!Ya estamos en vivo¡
bit.ly/jm_live
La idea de ‘Live’
• Reuniones intermedias entre cada meetup
presencial en CDMX
• Para desarrolladores que no pueden asisti...
Anuncio parroquial
Nuevo libro por
Javeros Mexicanos
Raul Estrada (@BusinessRul)
Isaac Ruiz Guerra (@rugi)
bit.ly/book_smack
Reactive
Programming
Reactive Programming
• “Reactive Programming” es programar con flujos de
datos asíncronos.
• Flujo de datos (Data Stream): ...
Functional
Reactive Programming
• Functional programming
• https://maryrosecook.com/blog/post/a-practical-
introduction-to...
ReactiveX
Reactive eXtensions
• Creado en Microsoft por Erik Meijer
• Colección de funciones útiles para hacer
programació...
ReactiveX
• Observable: fuente de flujos de datos (sender).
• Observer: Escucha los valores emitidos (receiver)
• El Observ...
Observable Observer
Pattern
• Permite operaciones concurrentes: el Observer
no necesita bloquear mientras espera que el
Ob...
RxJava
RxJava
• Proyecto Open Source con Licencia Apache.
• Implementación en Java de ReactiveX de
Microsoft
• El API de Netflix l...
RxJava Features
• Composable: Fácilmente se puede encadenar o
combinar
• Flexible: Se puede usar para emitir:
• Un valor e...
Usando Iterables
• Antes de reactivo
1. Invocar un método
2. Esperar el resultado
3. Almacenar el resultado en una variabl...
Usando Observables
1. Definir un Observer que especifica que hacer
con cada valor emitido
2. Invocar un método que regrese u...
En RxJava
• El método Subscribe conecta un Observer a un
Observable
• Una ves suscrito, no hay necesidad de bloquear
el hi...
Interface rx.Observer
public interface rx.Observer<T> {

void onCompleted();



void onError(Throwable e);



void onNext(...
void onCompleted();


/**

* Notifies the Observer that the
* {@link Observable} has finished sending
* push-based notific...
void onCompleted();
• El Observable invoca este método después de
que se invocó el método onNext por ultima
ocasión y no e...
void onError(Throwable e);
/**

* Notifies the Observer that the {@link Observable}
* has experienced an error condition.
...
void onError(Throwable e);
• El Observable invoca este método para indicar
que ha fallado al obtener la información
espera...
void onNext(T t)
/**

* Provides the Observer with a new item to observe.

* <p>

* The {@link Observable} may call this m...
void onNext(T t)
• El Observable invoca este método cada vez que
el Observable emite un elemento.
• Este método puede ser ...
Uso sencillo
public Observable<Double>
dollarToCurrencyExchangeRate(String targetCurrencyCode) {

// se crea de alguna man...
Composing el Observable
public void foo() {

dollarToCurrencyExchangeRate("MXN")

.throttleWithTimeout(2, TimeUnit.MINUTES...
¿Como esta
implementado el Observable?
• ¿Tal vez ejecuta su lógica en el hilo del subscriptor?
• ¿Tal vez delega parte de...
Consumiendo Observables
Modo largo…


rx.Observable.just(1, 2, 3)

.subscribe(new rx.Observer<Integer>() {

@Override

pub...
Consumiendo Observables
Modo corto Java 8.


rx.Observable.just(1, 2, 3)

.subscribe(

value ->

System.out.println(

Stri...
Operadores doOn*
rx.Observable.just(1, 2, 3, 4, 5)

.doOnNext(value -> {

if (Integer.valueOf(4).equals(value)) {

throw n...
Creando Observable
de forma explicita.
rx.Observable.<Integer>create(subscriber -> {

try {

for (int i = 0; i < 5; i++) {...
Como crear Observables
Manipulando
Observable
Transformando data map
rx.Observable.just(1, 2, 3, 4, 5)

.map(value -> String
.format("Value: %s", value.toString()))

.s...
Combinando Observables
Filtrando
Limitando elementos
Ejercicio 1
Implementar la kata
FizzBuzz
http://codingdojo.org/cgi-bin/index.pl?KataFizzBuzz
https://en.wikipedia.org/wiki...
Backpressure
• ¿Que ocurre si un Observable esta emitiendo elementos más rápido de lo que
el Observer puede procesarlos?
•...
Debounce
throttleFirst
throttleWithTimeout
List<Observable<byte[]>> observables =

//obtengo todas las instancias de los servicios

discoveryClient.getInstances("ser...


//Genero un solo Observable a partir de todos

Observable.merge(observables)

//Si algo falla al obtener el archivo del
...
A seguir
• Project Reactor
• https://projectreactor.io/
• Akka
• http://akka.io/
• Reactive Streams
• http://www.reactive-...
JVM Reactive Programming
JVM Reactive Programming
JVM Reactive Programming
Próximos SlideShares
Carregando em…5
×

JVM Reactive Programming

967 visualizações

Publicada em

Presentación sobre Reactive Programming en la JVM para el meetup JVM_MX.

Se mostraron conceptos sobre Reactive Programming y Functional Reactive Programming con la biblioteca RxJava de Netflix.

Publicada em: Tecnologia
  • Seja o primeiro a comentar

JVM Reactive Programming

  1. 1. JVM Reactive Programming Mexico City JVM Group October 2016 domix domix coderDog
  2. 2. !Gracias por estar aqui¡
  3. 3. !Ya estamos en vivo¡
  4. 4. bit.ly/jm_live
  5. 5. La idea de ‘Live’ • Reuniones intermedias entre cada meetup presencial en CDMX • Para desarrolladores que no pueden asistir • Para expositores nacionales o internacionales • Esfuerzo paralelo a las actividades de JVM_MX • YOLO
  6. 6. Anuncio parroquial
  7. 7. Nuevo libro por Javeros Mexicanos
  8. 8. Raul Estrada (@BusinessRul) Isaac Ruiz Guerra (@rugi)
  9. 9. bit.ly/book_smack
  10. 10. Reactive Programming
  11. 11. Reactive Programming • “Reactive Programming” es programar con flujos de datos asíncronos. • Flujo de datos (Data Stream): Una secuencia de valores • Modelo de programación basado en el principio de empujar (push) en lugar de obtener (pull). • Los valores se “emiten” cuando están listos, no cuando se solicitan de una forma no-bloqueante (non-blocking) • Se permite ejecutar operaciones en paralelo en lugar de forma serial.
  12. 12. Functional Reactive Programming • Functional programming • https://maryrosecook.com/blog/post/a-practical- introduction-to-functional-programming • Lleva a Reactive Programming al siguiente nivel. • Permute aplicar funciones al flujo de datos. • map, filter, zip, take, etc.. • Integra flujo de tiempo y los eventos de composición en la programación funcional.
  13. 13. ReactiveX Reactive eXtensions • Creado en Microsoft por Erik Meijer • Colección de funciones útiles para hacer programación reactiva. • ReactiveX esta implementado en mas de 10 lenguajes. • RxJava es la implementación de ReactiveX, fue escrita por el equipo de Netflix
  14. 14. ReactiveX • Observable: fuente de flujos de datos (sender). • Observer: Escucha los valores emitidos (receiver) • El Observer se suscribe (escucha) al Observable • Los Observers reaccionan a cualquier elemento o secuencias de elementos que emita el Observable • Muchos Observers pueden suscribirse al mismo Observable.
  15. 15. Observable Observer Pattern • Permite operaciones concurrentes: el Observer no necesita bloquear mientras espera que el Observable emita valores • El Observer espera a recibir valores cuando el Observable esta listo para emitirlos • Sobre la base de empuje (push) en lugar de obtener (pull)
  16. 16. RxJava
  17. 17. RxJava • Proyecto Open Source con Licencia Apache. • Implementación en Java de ReactiveX de Microsoft • El API de Netflix la usa para hacer la capa de servicio completamente asíncrona. • El objetivo es la JVM no el lenguaje. • Existe soporte para Java, Groovy, Clojure, y Scala
  18. 18. RxJava Features • Composable: Fácilmente se puede encadenar o combinar • Flexible: Se puede usar para emitir: • Un valor escalar (network result) • Secuencia (elementos en una lista) • Flujos infinitos (sensores de clima) • Mitiga el callback hell: Fácilmente se puede transformar un flujo asíncrono en otro
  19. 19. Usando Iterables • Antes de reactivo 1. Invocar un método 2. Esperar el resultado 3. Almacenar el resultado en una variable 4. Usar la variable para hacer algo util.
  20. 20. Usando Observables 1. Definir un Observer que especifica que hacer con cada valor emitido 2. Invocar un método que regrese un Observable 3. Suscribirse el Observer al Observable. Esto le dice al Observable que tiene un subscriptor esperando a recibir valores cuando estén disponibles.
  21. 21. En RxJava • El método Subscribe conecta un Observer a un Observable • Una ves suscrito, no hay necesidad de bloquear el hilo actual. • Los valores llegaran al Observer cuando estén listos y disponibles
  22. 22. Interface rx.Observer public interface rx.Observer<T> {
 void onCompleted();
 
 void onError(Throwable e);
 
 void onNext(T t);
 
 }
  23. 23. void onCompleted(); 
 /**
 * Notifies the Observer that the * {@link Observable} has finished sending * push-based notifications.
 * <p>
 * The {@link Observable} will not call * this method if it calls {@link #onError}.
 */
 void onCompleted();
  24. 24. void onCompleted(); • El Observable invoca este método después de que se invocó el método onNext por ultima ocasión y no encontró ningún error. • La llamada a onComplete finaliza la subscripción.
  25. 25. void onError(Throwable e); /**
 * Notifies the Observer that the {@link Observable} * has experienced an error condition.
 * <p>
 * If the {@link Observable} calls this method, it * will not thereafter call {@link #onNext} or
 * {@link #onCompleted}.
 * 
 * @param e
 * the exception encountered by the * Observable
 */
 void onError(Throwable e);
  26. 26. void onError(Throwable e); • El Observable invoca este método para indicar que ha fallado al obtener la información esperada o alguno otro problema. • Esto detiene al Observable y no hará mas invocaciones. • Envía la excepción que genero el problema.
  27. 27. void onNext(T t) /**
 * Provides the Observer with a new item to observe.
 * <p>
 * The {@link Observable} may call this method 0 or * more times.
 * <p>
 * The {@code Observable} will not call this method * again after it calls either {@link #onCompleted} * or {@link #onError}.
 * 
 * @param t
 * the item emitted by the Observable
 */
 void onNext(T t);
  28. 28. void onNext(T t) • El Observable invoca este método cada vez que el Observable emite un elemento. • Este método puede ser invocado cualquier número de veces (de cero a muchos). • Siempre seguido por onError o onComplete (pero no ambos)
  29. 29. Uso sencillo public Observable<Double> dollarToCurrencyExchangeRate(String targetCurrencyCode) {
 // se crea de alguna manera el Observable
 return ...
 } public void foo() {
 dollarToCurrencyExchangeRate("MXN")
 .subscribe(System.out::println);
 }
  30. 30. Composing el Observable public void foo() {
 dollarToCurrencyExchangeRate("MXN")
 .throttleWithTimeout(2, TimeUnit.MINUTES)
 .distinctUntilChanged()
 .filter(value -> value > 0)
 .map(Object::toString)
 .subscribe(System.out::println);
 }

  31. 31. ¿Como esta implementado el Observable? • ¿Tal vez ejecuta su lógica en el hilo del subscriptor? • ¿Tal vez delega parte del trabajo a otros hilos? • ¿Usará NIO? • ¿Tal vez es un actor? • ¿Devolverá datos de un cache? • ¡Al Observer no le importa!
  32. 32. Consumiendo Observables Modo largo… 
 rx.Observable.just(1, 2, 3)
 .subscribe(new rx.Observer<Integer>() {
 @Override
 public void onCompleted() {
 System.out.println("No más elementos.");
 }
 
 @Override
 public void onError(Throwable e) {
 System.out.println(
 String.format("Ocurrio un problema: %s", e.getMessage()));
 }
 
 @Override
 public void onNext(Integer integer) {
 System.out.println(
 String.format("Valor recibido: %d", integer));
 }
 });
  33. 33. Consumiendo Observables Modo corto Java 8. 
 rx.Observable.just(1, 2, 3)
 .subscribe(
 value ->
 System.out.println(
 String.format("Valor recibido: %d", value)),
 throwable ->
 System.out.println(
 String.format("Ocurrio un problema: %s",
 throwable.getMessage())),
 () -> System.out.println("No más elementos."));
  34. 34. Operadores doOn* rx.Observable.just(1, 2, 3, 4, 5)
 .doOnNext(value -> {
 if (Integer.valueOf(4).equals(value)) {
 throw new RuntimeException("El cuatro es feo.");
 }
 })
 .doOnError(throwable -> System.out.println(
 String.format("Ocurrio un problema: %s",
 throwable.getMessage())))
 .doOnCompleted(() -> System.out.println("No más elementos."))
 .subscribe(value ->
 System.out.println(
 String.format("Valor recibido: %d", value)));
  35. 35. Creando Observable de forma explicita. rx.Observable.<Integer>create(subscriber -> {
 try {
 for (int i = 0; i < 5; i++) {
 subscriber.onNext(i);
 }
 // Si olvidamos invocar onCompleted se
 // pueden crear Observables sin fin.
 subscriber.onCompleted();
 } catch (Throwable cause) {
 subscriber.onError(cause);
 }
 });
  36. 36. Como crear Observables
  37. 37. Manipulando Observable
  38. 38. Transformando data map rx.Observable.just(1, 2, 3, 4, 5)
 .map(value -> String .format("Value: %s", value.toString()))
 .subscribe(System.out::println);
  39. 39. Combinando Observables
  40. 40. Filtrando
  41. 41. Limitando elementos
  42. 42. Ejercicio 1 Implementar la kata FizzBuzz http://codingdojo.org/cgi-bin/index.pl?KataFizzBuzz https://en.wikipedia.org/wiki/Fizz_buzz Hasta el número 20
  43. 43. Backpressure • ¿Que ocurre si un Observable esta emitiendo elementos más rápido de lo que el Observer puede procesarlos? • Cold Observable: • Emite una secuencia particular de elementos, puede empezar a emitirla cuando su Observer lo considere conveniente y a la tasa de entrega que el Observer desee, sin interferir la integridad de la secuencia. • Hot Observable: • Es un Observable que empieza a generar elementos inmediatamente cuando es creado. Los subscriptores pueden empezar a observar la secuencia de elementos emitidos a la mitad de la secuencia, empezando con el primer elemento emitido posterior al establecimiento de la subscripción. Dicho Observable emite elementos a su propio ritmo y es responsabilidad de los Observers mantener ese mismo ritmo.
  44. 44. Debounce
  45. 45. throttleFirst
  46. 46. throttleWithTimeout
  47. 47. List<Observable<byte[]>> observables =
 //obtengo todas las instancias de los servicios
 discoveryClient.getInstances("service_id").stream()
 //Obtengo su URI remota (host:port)
 .map(serviceInstance -> serviceInstance.getUri().toString())
 //Genera un Worker que hará el trabajo de pedirle //a cada instancia del servicio el archivo. //DownloadCacheWorker implementa java.util.concurrent.Callable
 .map(baseUrl -> new DownloadLocalCacheWorker(baseUrl, bucket, key))
 //Genero un Future para hacerlo asíncrono
 .map(callable -> ((ThreadPoolTaskExecutor) taskExecutor).submit(callable))
 //Lo convierto a Observable para facilitar //el manejo de errores
 .map(Observable::from)
 //Genero una lista de Observables
 .collect(Collectors.toList());
  48. 48. 
 //Genero un solo Observable a partir de todos
 Observable.merge(observables)
 //Si algo falla al obtener el archivo del //servicio remoto, simplemente regreso null
 .onErrorReturn(throwable -> {
 log.warn("No se encontró algo", throwable);
 return null;
 }).doOnCompleted(() -> {})
 //Descarto todos los null
 .filter(fileContent -> fileContent != null)
 //obtengo el primer resultado exitoso //(en teoría solo debe existir en un solo servidor)
 .firstOrDefault(null)
 //hago la llamada bloqueante
 .toBlocking()
 //aplico la lógica de manejo del archivo
 .subscribe(new DownloadLocalCacheObserver(response, key, notFound));

  49. 49. A seguir • Project Reactor • https://projectreactor.io/ • Akka • http://akka.io/ • Reactive Streams • http://www.reactive-streams.org/

×