SlideShare a Scribd company logo
1 of 85
Download to read offline
RxJava: Como compor sua aplicação
com Observables
async + callbacks
async + callbacks
Future<T>
Future<List<T>>
Future<T>
Future<List<T>>
Future<T>
Future<List<T>>
Future<List<Future<T>>>
Observable<T>
Future<T>
Future<List<T>>
Future<List<Future<T>>>
Tudo é um fluxo de dados
List<Order> getOrders(int customerId)
List<Product> getProducts(Order order)
ShippingStatus getShippingStatus(Order o, Product p)
getOrders → getProducts → getShippingStatus
List<Order> getOrders(int customerId)
List<Product> getProducts(Order order)
ShippingStatus getShippingStatus(Order o, Product p)
APIs blocantes
getOrders → getProducts → getShippingStatus
IPC via Apache HTTP
Memcached
Cassandra
Tomcat e Servlets
IPC via Apache HTTP
Memcached
Cassandra
Tomcat e Servlets
Todos blocantes
Fachada assíncrona
Observable<Order> getOrders(int customerId)
Observable<Product> getProducts(Order order)
Observable<ShippingStatus> getShippingStatus(Order o, Product p)
getOrdersAsync → getProductsAsync → getShippingStatusAsync
getOrders → getProducts → getShippingStatus
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
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));
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));
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));
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));
Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)
ShippingStatus getShippingStatus(Order o, Product p)
Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)
return Observable.defer(() -> {
return Observable.just(getShippingStatus(o, p));
}).subscribeOn(Schedulers.io());
Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)
return Observable.defer(() -> {
return Observable.just(getShippingStatus(o, p));
}).subscribeOn(Schedulers.io());
Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)
return Observable.defer(() -> {
return Observable.just(getShippingStatus(o, p));
}).subscribeOn(Schedulers.io());
Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)
return Observable.defer(() -> {
return Observable.just(getShippingStatus(o, p));
}).subscribeOn(Schedulers.io());
Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p)
return Observable.defer(() -> {
return Observable.just(getShippingStatus(o, p));
}).subscribeOn(Schedulers.io());
List<Order> orders = getOrders(1);
Observable<Order> orders = getOrdersAsync(1);
List<Order> orders = getOrders(1);
Observable<Order> orders = getOrdersAsync(1);
List<Order> orders = getOrders(1);
Observable<Order> orders = getOrdersAsync(1);
return Observable.defer(() -> {
return Observable.from(getOrders(customerId));
}).subscribeOn(Schedulers.io());
Observable<Order> orders = getOrdersAsync(1);
return Observable.defer(() -> {
return Observable.from(getOrders(customerId));
}).subscribeOn(Schedulers.io());
Observable<Order> orders = getOrdersAsync(1);
Observable<Order> orders = getOrdersAsync(1);
return Observable.defer(() -> {
return Observable.from(getOrders(customerId));
}).subscribeOn(Schedulers.io());
return Observable.defer(() -> {
return Observable.from(getOrders(customerId));
}).subscribeOn(Schedulers.io());
Observable<Order> orders = getOrdersAsync(1);
return Observable.defer(() -> {
return Observable.from(getOrders(customerId));
}).subscribeOn(Schedulers.io());
Observable<Order> orders = getOrdersAsync(1);
Encapsulado por threads
JDBC?
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);
}
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);
}
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());
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());
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);
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);
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);
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);
ou com suporte a backpressure …
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
Observable.defer
Observable.from/just
Observable.subscribeOn
Observable.create
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 ...
}
}
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 ...
}
}
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 ...
}
}
Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) {
return getOrdersAsync(Integer.parseInt(customerId))
.limit(1)
.flatMap(o -> {
return getProductsAsync(o)
.flatMap(p -> {
return getShippingStatusAsync(o, p);
});
});
}
Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) {
return getOrdersAsync(Integer.parseInt(customerId))
.limit(1)
.flatMap(o -> {
return getProductsAsync(o)
.flatMap(p -> {
return getShippingStatusAsync(o, p);
});
});
}
Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) {
return getOrdersAsync(Integer.parseInt(customerId))
.limit(1)
.flatMap(o -> {
return getProductsAsync(o)
.flatMap(p -> {
return getShippingStatusAsync(o, p);
});
});
}
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 ...
}
}
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 ...
}
}
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 ...
}
}
Observable.toBlocking
Observable.toBlocking
Ponte entre sincrono e assincrono
Como adicionar código reativo
em um projeto existente?
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 ...
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();
});
Leia a documentação
Debug assincrono é mais difícil
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.class
at rx.exceptions.OnErrorThrowable.addValueAsLastCause(OnErrorThrowable.java:98)
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:58)
... 20 more
Stacktraces feios
C10k e além
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
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
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
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
Rx-Java - Como compor sua aplicacao com Observables

More Related Content

What's hot

The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 31 of 202
The Ring programming language version 1.8 book - Part 31 of 202The Ring programming language version 1.8 book - Part 31 of 202
The Ring programming language version 1.8 book - Part 31 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.4 book - Part 18 of 30
The Ring programming language version 1.4 book - Part 18 of 30The Ring programming language version 1.4 book - Part 18 of 30
The Ring programming language version 1.4 book - Part 18 of 30Mahmoud Samir Fayed
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2RORLAB
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 50 of 88
The Ring programming language version 1.3 book - Part 50 of 88The Ring programming language version 1.3 book - Part 50 of 88
The Ring programming language version 1.3 book - Part 50 of 88Mahmoud Samir Fayed
 
PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~
PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~
PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~Atsushi Torikoshi
 
Introduction to type classes
Introduction to type classesIntroduction to type classes
Introduction to type classesPawel Szulc
 
Introduction to type classes in 30 min
Introduction to type classes in 30 minIntroduction to type classes in 30 min
Introduction to type classes in 30 minPawel Szulc
 
The Ring programming language version 1.4.1 book - Part 3 of 31
The Ring programming language version 1.4.1 book - Part 3 of 31The Ring programming language version 1.4.1 book - Part 3 of 31
The Ring programming language version 1.4.1 book - Part 3 of 31Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 28 of 189
The Ring programming language version 1.6 book - Part 28 of 189The Ring programming language version 1.6 book - Part 28 of 189
The Ring programming language version 1.6 book - Part 28 of 189Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 177 of 181
The Ring programming language version 1.5.2 book - Part 177 of 181The Ring programming language version 1.5.2 book - Part 177 of 181
The Ring programming language version 1.5.2 book - Part 177 of 181Mahmoud Samir Fayed
 
OSGi World Congress Workshop Exercise - P Kriens
OSGi World Congress Workshop Exercise - P KriensOSGi World Congress Workshop Exercise - P Kriens
OSGi World Congress Workshop Exercise - P Kriensmfrancis
 
The Ring programming language version 1.5.2 book - Part 26 of 181
The Ring programming language version 1.5.2 book - Part 26 of 181The Ring programming language version 1.5.2 book - Part 26 of 181
The Ring programming language version 1.5.2 book - Part 26 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 35 of 180
The Ring programming language version 1.5.1 book - Part 35 of 180The Ring programming language version 1.5.1 book - Part 35 of 180
The Ring programming language version 1.5.1 book - Part 35 of 180Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210Mahmoud Samir Fayed
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
Mcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhMcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhDIVYA SINGH
 

What's hot (20)

The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202
 
The Ring programming language version 1.8 book - Part 31 of 202
The Ring programming language version 1.8 book - Part 31 of 202The Ring programming language version 1.8 book - Part 31 of 202
The Ring programming language version 1.8 book - Part 31 of 202
 
The Ring programming language version 1.4 book - Part 18 of 30
The Ring programming language version 1.4 book - Part 18 of 30The Ring programming language version 1.4 book - Part 18 of 30
The Ring programming language version 1.4 book - Part 18 of 30
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
 
Test
TestTest
Test
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194
 
The Ring programming language version 1.3 book - Part 50 of 88
The Ring programming language version 1.3 book - Part 50 of 88The Ring programming language version 1.3 book - Part 50 of 88
The Ring programming language version 1.3 book - Part 50 of 88
 
PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~
PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~
PostgreSQL10の新機能 ~ロジカルレプリケーションを中心に~
 
Introduction to type classes
Introduction to type classesIntroduction to type classes
Introduction to type classes
 
Introduction to type classes in 30 min
Introduction to type classes in 30 minIntroduction to type classes in 30 min
Introduction to type classes in 30 min
 
The Ring programming language version 1.4.1 book - Part 3 of 31
The Ring programming language version 1.4.1 book - Part 3 of 31The Ring programming language version 1.4.1 book - Part 3 of 31
The Ring programming language version 1.4.1 book - Part 3 of 31
 
The Ring programming language version 1.6 book - Part 28 of 189
The Ring programming language version 1.6 book - Part 28 of 189The Ring programming language version 1.6 book - Part 28 of 189
The Ring programming language version 1.6 book - Part 28 of 189
 
The Ring programming language version 1.5.2 book - Part 177 of 181
The Ring programming language version 1.5.2 book - Part 177 of 181The Ring programming language version 1.5.2 book - Part 177 of 181
The Ring programming language version 1.5.2 book - Part 177 of 181
 
OSGi World Congress Workshop Exercise - P Kriens
OSGi World Congress Workshop Exercise - P KriensOSGi World Congress Workshop Exercise - P Kriens
OSGi World Congress Workshop Exercise - P Kriens
 
The Ring programming language version 1.5.2 book - Part 26 of 181
The Ring programming language version 1.5.2 book - Part 26 of 181The Ring programming language version 1.5.2 book - Part 26 of 181
The Ring programming language version 1.5.2 book - Part 26 of 181
 
The Ring programming language version 1.5.1 book - Part 35 of 180
The Ring programming language version 1.5.1 book - Part 35 of 180The Ring programming language version 1.5.1 book - Part 35 of 180
The Ring programming language version 1.5.1 book - Part 35 of 180
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184
 
The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210The Ring programming language version 1.9 book - Part 91 of 210
The Ring programming language version 1.9 book - Part 91 of 210
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
Mcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhMcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singh
 

Similar to Rx-Java - Como compor sua aplicacao com Observables

Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for AndroidTomáš Kypta
 
Formal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractFormal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractGera Shegalov
 
«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС
«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС
«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС2ГИС Технологии
 
Практическое применения Akka Streams
Практическое применения Akka StreamsПрактическое применения Akka Streams
Практическое применения Akka StreamsAlexey Romanchuk
 
(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)Stas Rivkin
 
Implementing pseudo-keywords through Functional Programing
Implementing pseudo-keywords through Functional ProgramingImplementing pseudo-keywords through Functional Programing
Implementing pseudo-keywords through Functional ProgramingVincent Pradeilles
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Leonardo Borges
 
Reactive Programming on Android
Reactive Programming on AndroidReactive Programming on Android
Reactive Programming on AndroidGuilherme Branco
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Fwdays
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streamsBartosz Sypytkowski
 

Similar to Rx-Java - Como compor sua aplicacao com Observables (20)

Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Formal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractFormal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction Contract
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС
«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС
«Практическое применение Akka Streams» — Алексей Романчук, 2ГИС
 
Практическое применения Akka Streams
Практическое применения Akka StreamsПрактическое применения Akka Streams
Практическое применения Akka Streams
 
(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
2013 28-03-dak-why-fp
2013 28-03-dak-why-fp2013 28-03-dak-why-fp
2013 28-03-dak-why-fp
 
Implementing pseudo-keywords through Functional Programing
Implementing pseudo-keywords through Functional ProgramingImplementing pseudo-keywords through Functional Programing
Implementing pseudo-keywords through Functional Programing
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Reactive Programming on Android
Reactive Programming on AndroidReactive Programming on Android
Reactive Programming on Android
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
 
Nancy + rest mow2012
Nancy + rest   mow2012Nancy + rest   mow2012
Nancy + rest mow2012
 

Recently uploaded

Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 

Recently uploaded (20)

Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

Rx-Java - Como compor sua aplicacao com Observables

  • 1. RxJava: Como compor sua aplicação com Observables
  • 2.
  • 9. Tudo é um fluxo de dados
  • 10. List<Order> getOrders(int customerId) List<Product> getProducts(Order order) ShippingStatus getShippingStatus(Order o, Product p) getOrders → getProducts → getShippingStatus
  • 11. List<Order> getOrders(int customerId) List<Product> getProducts(Order order) ShippingStatus getShippingStatus(Order o, Product p) APIs blocantes getOrders → getProducts → getShippingStatus
  • 12. IPC via Apache HTTP Memcached Cassandra Tomcat e Servlets
  • 13. IPC via Apache HTTP Memcached Cassandra Tomcat e Servlets Todos blocantes
  • 15. Observable<Order> getOrders(int customerId) Observable<Product> getProducts(Order order) Observable<ShippingStatus> getShippingStatus(Order o, Product p) getOrdersAsync → getProductsAsync → getShippingStatusAsync getOrders → getProducts → getShippingStatus
  • 16. 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
  • 17. 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));
  • 18. 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));
  • 19. 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));
  • 20. 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));
  • 21. Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p) ShippingStatus getShippingStatus(Order o, Product p)
  • 22. Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p) return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p)); }).subscribeOn(Schedulers.io());
  • 23. Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p) return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p)); }).subscribeOn(Schedulers.io());
  • 24. Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p) return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p)); }).subscribeOn(Schedulers.io());
  • 25. Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p) return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p)); }).subscribeOn(Schedulers.io());
  • 26. Observable<ShippingStatus> getShippingStatusAsync(Order o, Product p) return Observable.defer(() -> { return Observable.just(getShippingStatus(o, p)); }).subscribeOn(Schedulers.io());
  • 27. List<Order> orders = getOrders(1); Observable<Order> orders = getOrdersAsync(1);
  • 28. List<Order> orders = getOrders(1); Observable<Order> orders = getOrdersAsync(1);
  • 29. List<Order> orders = getOrders(1); Observable<Order> orders = getOrdersAsync(1);
  • 30. return Observable.defer(() -> { return Observable.from(getOrders(customerId)); }).subscribeOn(Schedulers.io()); Observable<Order> orders = getOrdersAsync(1);
  • 31. return Observable.defer(() -> { return Observable.from(getOrders(customerId)); }).subscribeOn(Schedulers.io()); Observable<Order> orders = getOrdersAsync(1);
  • 32. Observable<Order> orders = getOrdersAsync(1); return Observable.defer(() -> { return Observable.from(getOrders(customerId)); }).subscribeOn(Schedulers.io());
  • 33. return Observable.defer(() -> { return Observable.from(getOrders(customerId)); }).subscribeOn(Schedulers.io()); Observable<Order> orders = getOrdersAsync(1);
  • 34. return Observable.defer(() -> { return Observable.from(getOrders(customerId)); }).subscribeOn(Schedulers.io()); Observable<Order> orders = getOrdersAsync(1);
  • 36. 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); }
  • 37. 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); }
  • 38. 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());
  • 39. 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());
  • 40. 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);
  • 41. 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);
  • 42. 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);
  • 43. 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);
  • 44. ou com suporte a backpressure …
  • 45. 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());
  • 46. 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());
  • 47. 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());
  • 48. 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());
  • 49. 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());
  • 50. 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());
  • 51. 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());
  • 52. 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());
  • 53. 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());
  • 54. 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());
  • 55. 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());
  • 56. 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());
  • 57. 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());
  • 58. 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());
  • 60. 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 ... } }
  • 61. 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 ... } }
  • 62. 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 ... } }
  • 63. Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) { return getOrdersAsync(Integer.parseInt(customerId)) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }); }
  • 64. Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) { return getOrdersAsync(Integer.parseInt(customerId)) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }); }
  • 65. Observable<ShippingStatus> getShippingStatusForCustomerOrdersAsync(String customerId) { return getOrdersAsync(Integer.parseInt(customerId)) .limit(1) .flatMap(o -> { return getProductsAsync(o) .flatMap(p -> { return getShippingStatusAsync(o, p); }); }); }
  • 66. 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 ... } }
  • 67. 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 ... } }
  • 68. 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 ... } }
  • 71. Como adicionar código reativo em um projeto existente?
  • 72. 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 ...
  • 73. 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(); });
  • 75.
  • 76.
  • 77. Debug assincrono é mais difícil
  • 78. 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.class at rx.exceptions.OnErrorThrowable.addValueAsLastCause(OnErrorThrowable.java:98) at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:58) ... 20 more Stacktraces feios
  • 79.
  • 81. 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
  • 82. 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
  • 83. 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
  • 84. 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