Top Banner
RxJava: Como compor sua aplicação com Observables
85

Rx-Java - Como compor sua aplicacao com Observables

Feb 21, 2017

Download

Software

lokimad
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Rx-Java - Como compor sua aplicacao com Observables

RxJava: Como compor sua aplicaçãocom Observables

Page 2: Rx-Java - Como compor sua aplicacao com Observables
Page 3: Rx-Java - Como compor sua aplicacao com Observables

async + callbacks

Page 4: Rx-Java - Como compor sua aplicacao com Observables

async + callbacks

Page 5: Rx-Java - Como compor sua aplicacao com Observables

Future<T> Future<List<T>>

Page 6: Rx-Java - Como compor sua aplicacao com Observables

Future<T> Future<List<T>>

Page 7: Rx-Java - Como compor sua aplicacao com Observables

Future<T> Future<List<T>>

Future<List<Future<T>>>

Page 8: Rx-Java - Como compor sua aplicacao com Observables

Observable<T>

Future<T> Future<List<T>>

Future<List<Future<T>>>

Page 9: Rx-Java - Como compor sua aplicacao com Observables

Tudo é um fluxo de dados

Page 10: Rx-Java - Como compor sua aplicacao com Observables

List<Order> getOrders(int customerId)List<Product> getProducts(Order order)ShippingStatus getShippingStatus(Order o, Product p)

getOrders → getProducts → getShippingStatus

Page 11: Rx-Java - Como compor sua aplicacao com Observables

List<Order> getOrders(int customerId)List<Product> getProducts(Order order)ShippingStatus getShippingStatus(Order o, Product p)

APIs blocantes

getOrders → getProducts → getShippingStatus

Page 12: Rx-Java - Como compor sua aplicacao com Observables

IPC via Apache HTTP Memcached Cassandra

Tomcat e Servlets

Page 13: Rx-Java - Como compor sua aplicacao com Observables

IPC via Apache HTTP Memcached Cassandra

Tomcat e Servlets

Todos blocantes

Page 14: Rx-Java - Como compor sua aplicacao com Observables

Fachada assíncrona

Page 15: Rx-Java - Como compor sua aplicacao com Observables

Observable<Order> getOrders(int customerId)Observable<Product> getProducts(Order order)Observable<ShippingStatus> getShippingStatus(Order o, Product p)

getOrdersAsync → getProductsAsync → getShippingStatusAsync

getOrders → getProducts → getShippingStatus

Page 16: Rx-Java - Como compor sua aplicacao com Observables

Observable<Order> getOrders(int customerId)Observable<Product> getProducts(Order order)Observable<ShippingStatus> getShippingStatus(Order o, Product p)

getOrdersAsync → getProductsAsync → getShippingStatusAsync

API observável

getOrders → getProducts → getShippingStatus

Page 17: Rx-Java - Como compor sua aplicacao com Observables

getOrdersAsync(1) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }) .forEach(s -> System.out.println(Thread.currentThread() + " [Async] Shipping Status: " + s));

Page 18: Rx-Java - Como compor sua aplicacao com Observables

getOrdersAsync(1) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }) .forEach(s -> System.out.println(Thread.currentThread() + " [Async] Shipping Status: " + s));

Page 19: Rx-Java - Como compor sua aplicacao com Observables

getOrdersAsync(1) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }) .forEach(s -> System.out.println(Thread.currentThread() + " [Async] Shipping Status: " + s));

Page 20: Rx-Java - Como compor sua aplicacao com Observables

getOrdersAsync(1) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }) .forEach(s -> System.out.println(Thread.currentThread() + " [Async] Shipping Status: " + s));

Page 21: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)

ShippingStatus getShippingStatus(Order o, Product p)

Page 22: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)

return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p));}).subscribeOn(Schedulers.io());

Page 23: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)

return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p));}).subscribeOn(Schedulers.io());

Page 24: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)

return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p));}).subscribeOn(Schedulers.io());

Page 25: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)

return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p));}).subscribeOn(Schedulers.io());

Page 26: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)

return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p));}).subscribeOn(Schedulers.io());

Page 27: Rx-Java - Como compor sua aplicacao com Observables

List<Order> orders = getOrders(1);

Observable<Order> orders = getOrdersAsync(1);

Page 28: Rx-Java - Como compor sua aplicacao com Observables

List<Order> orders = getOrders(1);

Observable<Order> orders = getOrdersAsync(1);

Page 29: Rx-Java - Como compor sua aplicacao com Observables

List<Order> orders = getOrders(1);

Observable<Order> orders = getOrdersAsync(1);

Page 30: Rx-Java - Como compor sua aplicacao com Observables

return Observable.defer(() -> { return Observable.from(getOrders(customerId));}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 31: Rx-Java - Como compor sua aplicacao com Observables

return Observable.defer(() -> { return Observable.from(getOrders(customerId));}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 32: Rx-Java - Como compor sua aplicacao com Observables

Observable<Order> orders = getOrdersAsync(1);

return Observable.defer(() -> { return Observable.from(getOrders(customerId));}).subscribeOn(Schedulers.io());

Page 33: Rx-Java - Como compor sua aplicacao com Observables

return Observable.defer(() -> { return Observable.from(getOrders(customerId));}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 34: Rx-Java - Como compor sua aplicacao com Observables

return Observable.defer(() -> { return Observable.from(getOrders(customerId));}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 35: Rx-Java - Como compor sua aplicacao com Observables

Encapsulado por threads

JDBC?

Page 36: Rx-Java - Como compor sua aplicacao com Observables

List<Order> orders = getOrders(1);

try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); ArrayList<Order> orders = new ArrayList<>(); while (rs.next()) { orders.add(new Order(rs.getInt(1))); } rs.close(); return orders;} catch (Exception e) { throw new RuntimeException(e);}

Page 37: Rx-Java - Como compor sua aplicacao com Observables

List<Order> orders = getOrders(1);

try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); ArrayList<Order> orders = new ArrayList<>(); while (rs.next()) { orders.add(new Order(rs.getInt(1))); } rs.close(); return orders;} catch (Exception e) { throw new RuntimeException(e);}

Page 38: Rx-Java - Como compor sua aplicacao com Observables

Observable<Order> orders = getOrdersAsync(1);

return Observable.<Order> create(o -> { try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); while (rs.next() && !o.isUnsubscribed()) { o.onNext(new Order(rs.getInt(1))); } rs.close(); o.onCompleted(); } catch (Exception e) { o.onError(e); }}).subscribeOn(Schedulers.io());

Page 39: Rx-Java - Como compor sua aplicacao com Observables

Observable<Order> orders = getOrdersAsync(1);

return Observable.<Order> create(o -> { try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); while (rs.next() && !o.isUnsubscribed()) { o.onNext(new Order(rs.getInt(1))); } rs.close(); o.onCompleted(); } catch (Exception e) { o.onError(e); }}).subscribeOn(Schedulers.io());

Page 40: Rx-Java - Como compor sua aplicacao com Observables

return Observable.<Order> create(o -> { try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); while (rs.next() && !o.isUnsubscribed()) { o.onNext(new Order(rs.getInt(1))); } rs.close(); o.onCompleted(); } catch (Exception e) { o.onError(e); }}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 41: Rx-Java - Como compor sua aplicacao com Observables

return Observable.<Order> create(o -> { try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); while (rs.next() && !o.isUnsubscribed()) { o.onNext(new Order(rs.getInt(1))); } rs.close(); o.onCompleted(); } catch (Exception e) { o.onError(e); }}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 42: Rx-Java - Como compor sua aplicacao com Observables

return Observable.<Order> create(o -> { try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); while (rs.next() && !o.isUnsubscribed()) { o.onNext(new Order(rs.getInt(1))); } rs.close(); o.onCompleted(); } catch (Exception e) { o.onError(e); }}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 43: Rx-Java - Como compor sua aplicacao com Observables

return Observable.<Order> create(o -> { try (Connection c = Database.getConnection()) { ResultSet rs = c.createStatement() .executeQuery("select * from orders"); while (rs.next() && !o.isUnsubscribed()) { o.onNext(new Order(rs.getInt(1))); } rs.close(); o.onCompleted(); } catch (Exception e) { o.onError(e); }}).subscribeOn(Schedulers.io());

Observable<Order> orders = getOrdersAsync(1);

Page 44: Rx-Java - Como compor sua aplicacao com Observables

ou com suporte a backpressure …

Page 45: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 46: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 47: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 48: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 49: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 50: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 51: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 52: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 53: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 54: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 55: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 56: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 57: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 58: Rx-Java - Como compor sua aplicacao com Observables

return Observable.create(SyncOnSubscribe.<Order, ResultSet> create(s -> { ResultSet rs = s.state(); try { if (rs.next()) { s.onNext(new Order(rs.getInt(1))); } else { s.onCompleted(); } } catch (SQLException e) { s.onError(e); }}, s -> { Connection c = Database.getConnection(); try { Statement stmt = c.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); return stmt.executeQuery("select * from orders"); } catch (SQLException e) { s.onError(e); return null; }}, rs -> rs.close() } // ignoring try/catch for slide brevity)).subscribeOn(Schedulers.io());

Page 59: Rx-Java - Como compor sua aplicacao com Observables

Observable.defer Observable.from/just

Observable.subscribeOn

Observable.create

Page 60: Rx-Java - Como compor sua aplicacao com Observables

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // perform service composition asynchronously getShippingStatusForCustomerOrdersAsync(req.getParameter(“customerId")) .toBlocking() // block on servlet thread .forEach(status -> { try { // write output using blocking IO resp.getWriter().write(status.toString()); } catch (Exception e) { throw new RuntimeException("unable to write", e); } }); } catch (Exception e) { // toBlocking and forEach will convert async onError events into thrown exceptions resp.setStatus(500); // write and log error ... }}

Page 61: Rx-Java - Como compor sua aplicacao com Observables

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // perform service composition asynchronously getShippingStatusForCustomerOrdersAsync(req.getParameter("customerId")) .toBlocking() // block on servlet thread .forEach(status -> { try { // write output using blocking IO resp.getWriter().write(status.toString()); } catch (Exception e) { throw new RuntimeException("unable to write", e); } }); } catch (Exception e) { // toBlocking and forEach will convert async onError events into thrown exceptions resp.setStatus(500); // write and log error ... }}

Page 62: Rx-Java - Como compor sua aplicacao com Observables

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // perform service composition asynchronously getShippingStatusForCustomerOrdersAsync(req.getParameter("customerId")) .toBlocking() // block on servlet thread .forEach(status -> { try { // write output using blocking IO resp.getWriter().write(status.toString()); } catch (Exception e) { throw new RuntimeException("unable to write", e); } }); } catch (Exception e) { // toBlocking and forEach will convert async onError events into thrown exceptions resp.setStatus(500); // write and log error ... }}

Page 63: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) { return getOrdersAsync(Integer.parseInt(customerId)) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); });}

Page 64: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) { return getOrdersAsync(Integer.parseInt(customerId)) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); });}

Page 65: Rx-Java - Como compor sua aplicacao com Observables

Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) { return getOrdersAsync(Integer.parseInt(customerId)) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); });}

Page 66: Rx-Java - Como compor sua aplicacao com Observables

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // perform service composition asynchronously getShippingStatusForCustomerOrdersAsync(req.getParameter("customerId")) .toBlocking() // block on servlet thread .forEach(status -> { try { // write output using blocking IO resp.getWriter().write(status.toString()); } catch (Exception e) { throw new RuntimeException("unable to write", e); } }); } catch (Exception e) { // toBlocking and forEach will convert async onError events into thrown exceptions resp.setStatus(500); // write and log error ... }}

Page 67: Rx-Java - Como compor sua aplicacao com Observables

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // perform service composition asynchronously getShippingStatusForCustomerOrdersAsync(req.getParameter("customerId")) .toBlocking() // block on servlet thread .forEach(status -> { try { // write output using blocking IO resp.getWriter().write(status.toString()); } catch (Exception e) { throw new RuntimeException("unable to write", e); } }); } catch (Exception e) { // toBlocking and forEach will convert async onError events into thrown exceptions resp.setStatus(500); // write and log error ... }}

Page 68: Rx-Java - Como compor sua aplicacao com Observables

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // perform service composition asynchronously getShippingStatusForCustomerOrdersAsync(req.getParameter("customerId")) .toBlocking() // block on servlet thread .forEach(status -> { try { // write output using blocking IO resp.getWriter().write(status.toString()); } catch (Exception e) { throw new RuntimeException("unable to write", e); } }); } catch (Exception e) { // toBlocking and forEach will convert async onError events into thrown exceptions resp.setStatus(500); // write and log error ... }}

Page 69: Rx-Java - Como compor sua aplicacao com Observables

Observable.toBlocking

Page 70: Rx-Java - Como compor sua aplicacao com Observables

Observable.toBlocking

Ponte entre sincrono e assincrono

Page 71: Rx-Java - Como compor sua aplicacao com Observables

Como adicionar código reativoem um projeto existente?

Page 72: Rx-Java - Como compor sua aplicacao com Observables

Iterable<String> is = Arrays.asList("a", "b", "c");ArrayList<String> ts = new ArrayList<>();for(String s : is) { ts.add(s + "-modified");}// do stuff with ts ...

Observable<String> os = Observable.just("a", "b", "c");os.map(s -> s + "-modified");// do stuff with os ...

Page 73: Rx-Java - Como compor sua aplicacao com Observables

try { for (String s : is) { ts.add(s + "-modified"); }} catch (Exception e) { // do something with exception}

os.map(s -> s + "-modified") .onErrorResumeNext(exception -> { // do something with exception return Observable.empty(); });

Page 74: Rx-Java - Como compor sua aplicacao com Observables

Leia a documentação

Page 75: Rx-Java - Como compor sua aplicacao com Observables
Page 76: Rx-Java - Como compor sua aplicacao com Observables
Page 77: Rx-Java - Como compor sua aplicacao com Observables

Debug assincrono é mais difícil

Page 78: Rx-Java - Como compor sua aplicacao com Observables

java.lang.RuntimeException: failure!at jdbc.Test.lambda$19(Test.java:63)at jdbc.Test$$Lambda$8/888452645.call(Unknown Source)at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55)at rx.internal.operators.OperatorSubscribeOn$1$1$1.onNext(OperatorSubscribeOn.java:76)at rx.observables.AbstractOnSubscribe$SubscriptionState.accept(AbstractOnSubscribe.java:533)at rx.observables.AbstractOnSubscribe$SubscriptionProducer.doNext(AbstractOnSubscribe.java:367)at rx.observables.AbstractOnSubscribe$SubscriptionProducer.request(AbstractOnSubscribe.java:345)at rx.internal.operators.OperatorSubscribeOn$1$1$1$1.request(OperatorSubscribeOn.java:88)at rx.Subscriber.setProducer(Subscriber.java:177)at rx.Subscriber.setProducer(Subscriber.java:171)at rx.internal.operators.OperatorSubscribeOn$1$1$1.setProducer(OperatorSubscribeOn.java:81)at rx.observables.AbstractOnSubscribe.call(AbstractOnSubscribe.java:191)at rx.observables.AbstractOnSubscribe$LambdaOnSubscribe.call(AbstractOnSubscribe.java:274)at rx.Observable.unsafeSubscribe(Observable.java:7495)at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)

Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: jdbc.Product.classat rx.exceptions.OnErrorThrowable.addValueAsLastCause(OnErrorThrowable.java:98)at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:58)... 20 more

Stacktraces feios

Page 79: Rx-Java - Como compor sua aplicacao com Observables
Page 80: Rx-Java - Como compor sua aplicacao com Observables

C10k e além

Page 81: Rx-Java - Como compor sua aplicacao com Observables

0%

25%

50%

75%

100%

50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 100010501100

RxNetty Tomcat

Uso de CPU em percentual

concurrent clients

Page 82: Rx-Java - Como compor sua aplicacao com Observables

0ms

0.225ms

0.45ms

0.675ms

0.9ms

50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 100010501100

RxNetty Tomcat

Consumo de CPU por requisição

concurrent clients

Page 83: Rx-Java - Como compor sua aplicacao com Observables

0rps

1250rps

2500rps

3750rps

5000rps

50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 100010501100

RxNetty Tomcat

Vazão

concurrent clients

Page 84: Rx-Java - Como compor sua aplicacao com Observables

0

400000

800000

1200000

1600000

50 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 100010501100

RxNetty Tomcat

Migração de thread

concurrent clients

Page 85: Rx-Java - Como compor sua aplicacao com Observables