Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RxJava in Microservices World

RxJava in Microservices World

Piotr Kafel

January 27, 2016
Tweet

More Decks by Piotr Kafel

Other Decks in Programming

Transcript

  1. 26-27/05/2016
    RxJava in Microservices
    World
    Piotr Kafel (@PiotrKafel)

    View Slide

  2. 26-27/05/2016
    Microservices

    View Slide

  3. 26-27/05/2016
    Trade-offs

    View Slide

  4. 26-27/05/2016
    Microservices
    time

    View Slide

  5. 26-27/05/2016
    Microservices
    time

    View Slide

  6. 26-27/05/2016
    CompletableFuture
    CompletableFuture result = getUuid().thenApply(this::getString);
    public CompletableFuture getUuid() {
    // incredibly smart code goes here
    }
    public String getString(UUID uuid) {
    // incredibly smart code goes here
    }

    View Slide

  7. 26-27/05/2016
    CompletableFuture
    CompletableFuture>> ohMyGod = getUuids()
    .thenApply(uuids -> uuids.stream()
    .map(this::getString)
    .collect(Collectors.toList()));
    public CompletableFuture> getUuids() {
    // incredibly smart code goes here
    }
    public CompletableFuture getString(UUID uuid) {
    // incredibly smart code goes here
    }

    View Slide

  8. 26-27/05/2016
    Observable
    Observable result = getUuids().flatMap(this::getString);
    public Observable getUuids() {
    // incredibly smart code goes here
    }
    public Observable getString(UUID uuid) {
    // incredibly smart code goes here
    }

    View Slide

  9. 26-27/05/2016
    RxJava

    View Slide

  10. 26-27/05/2016
    Observable
    Observable.create(subscriber -> {
    subscriber.onNext("Hello World !");
    subscriber.onCompleted();
    }).forEach(System.out::println);

    View Slide

  11. 26-27/05/2016
    Observable
    Observable.create(subscriber -> {
    subscriber.onNext("Hello");
    subscriber.onNext("World");
    subscriber.onNext("!");
    subscriber.onCompleted();
    })
    .subscribeOn(Schedulers.newThread())
    .forEach(System.out::println);

    View Slide

  12. 26-27/05/2016
    Observable
    Observable.create(subscriber -> {
    try {
    subscriber.onNext(doSomething());
    subscriber.onCompleted();
    } catch(Exception e) {
    subscriber.onError(e);
    }
    }).forEach(
    i -> System.out.print(i),
    e -> e.printStackTrace()
    );

    View Slide

  13. 26-27/05/2016
    Documentation

    View Slide

  14. 26-27/05/2016
    Example
    public Observable retrieveDivisions (List divisions) {
    Locale locale = locale();
    return Observable.from(divisions)
    .flatMap(divisionId -> geoPlacesClient.getDivisionsById(divisionId))
    .filter(resp -> resp.status == SUCCESS)
    .flatMapIterable(resp -> resp.data)
    .filter(div -> div.status == Status.ACTIVE)
    .map(div -> new DealDivision(
    div.uuid.toString(), div.getNameOrDefault(locale)));
    }

    View Slide

  15. 26-27/05/2016
    Pattern
    doHttpCallForUUids()
    .buffer(50)
    .flatMap(listOfUuids -> doHttpCallForEntities(listOfUuids));

    View Slide

  16. 26-27/05/2016
    Pattern
    doHttpCall().retry(
    (i, throwable) -> i < 5 && throwable instanceof Status503Exception
    );

    View Slide

  17. 26-27/05/2016
    Pattern
    doHttpCall().retryWhen(errorObservable ->
    errorObservable
    .zipWith(Observable.range(1, numberOfRetries), Pair::of)
    .flatMap(pair -> {
    if(pair.getRight() == numberOfRetries) {
    return Observable.error(pair.getLeft());
    } else {
    return Observable.timer(wait, TimeUnit.MILLISECONDS);
    }
    }));

    View Slide

  18. 26-27/05/2016
    Pattern
    Observable.range(1, Integer.MAX_VALUE)
    .concatMap(page -> doHttpCall(id, page, DEFAULT_PER_PAGE_SIZE))
    .map(response -> response.getComments())
    .takeWhile(comments -> comments.size() > 0)

    View Slide

  19. 26-27/05/2016
    Adaptation
    Observable.defer(() -> Observable.just(completelySynchronousHttpCall()))
    .subscribeOn(Schedulers.io());

    View Slide

  20. 26-27/05/2016
    Testing
    TestSubscriber subscriber = new TestSubscriber<>();
    Observable.interval(100, TimeUnit.MILLISECONDS, Schedulers.computation())
    .take(5)
    .map(i -> i + " value")
    .subscribe(subscriber);
    subscriber.awaitTerminalEvent();
    subscriber.assertNoErrors();
    subscriber.assertValueCount(5);

    View Slide

  21. 26-27/05/2016
    Retrofit

    View Slide

  22. 26-27/05/2016
    Retrofit
    public interface InventoryUnitClient {
    @GET("/inventory/v2/{entity}/search/redemption")
    Observable getInventoryUnitRedemption(
    @Path("uuid") UUID uuid);
    @POST("/inventory/v2/{entity}/search/redemption")
    Observable redeemUnit(
    @Path("uuid") UUID uuid,
    @Body JsonHolder redemption);
    }

    View Slide

  23. 26-27/05/2016
    Hystrix

    View Slide

  24. 26-27/05/2016
    Hystrix
    public class CommandHelloWorld extends HystrixCommand {
    private final String name;
    public CommandHelloWorld(String name) {
    super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
    this.name = name;
    }
    @Override
    protected String run() {
    return "Hello " + name + "!";
    }
    }

    View Slide

  25. 26-27/05/2016
    Spring

    View Slide

  26. 26-27/05/2016
    Spring
    @RequestMapping(value = PATH_ACCOUNT_MANAGERS, method = RequestMethod.GET)
    public DeferredResult getAccountManagers() {
    DeferredResult result = new DeferredResult<>();
    getAccountManagersObservable().subscribe(
    item -> result.setResult(item),
    exception -> result.setErrorResult(exception)
    );
    return result;
    }

    View Slide

  27. 26-27/05/2016
    Wow, is it really that cool !?

    View Slide

  28. 26-27/05/2016
    That’s all folks !

    View Slide