Click here to load reader

Ubiratan Soares - Programação reativa funcional com RXJava - #JavaOneBR #oowBR

  • View
    132

  • Download
    0

Embed Size (px)

Text of Ubiratan Soares - Programação reativa funcional com RXJava - #JavaOneBR #oowBR

  • RXJAVAPROGRAMAO REATIVA FUNCIONAL COM

    UBIRATAN SOARESMARO / 2016

  • MOTIVAO

    Java8 trouxe uma API de Streams, que permite operaes comuns sobre colees como Map, Filter, Reduce

    Java9 trar uma API de ReactiveStreams, adotadando muitos conceitos presentes em RxJava diretamente no JDK

    Funcional Programming ajuda a escrever cdigo mais robusto e conciso de maneira geral

  • ERIK MEIJER

    Do ponto de vista de fluxo de dados, qual a diferena entre consultar o DB e processar as posies do ponteiro do mouse ???

  • VELHOS PROBLEMAS SEMPRE NA MODA

    Execuo orquestrada de cdigo de forma assncrona

    Execuo e sincronizao de processamento concorrente

    Tratamento de erros

    Escalabilidade

  • UMA NOVA FORMA DE PENSAR

    E se ao invs de buscar dados de forma assncrona, os dados chegassem at mim de forma assncrona ?

    Reativo : algo que reage a um estmulo !!!

    Fundamento matemtico : teoria da categorias !!!

  • POR QU REACTIVE PROGRAMMING

    As demandas atuais tipicamente pedem aplicaes

    Responsivas

    Resilientes

    Orientadas a eventos

    Escalveis

  • HANS DOCKTER

    Programar arte de encontrar as abstraes corretas

  • RELEITURA DE CONCEITOS

    Pensamento em termos de fluxo de dados : eventos discretos e fluxo desses eventos

    possvel reagir a eventos e combinar os mesmos

    O estado do sistema deve mudar conforme a passagem de eventos no tempo

    Eventos no fluxo so imutveis

    Sistema que idealmente nunca bloqueia (I/O, clculos, etc)

  • DADOS E SINCRONICIDADE

    Um valor Mltiplos valores

    Sncrona T getData( ) Iterable getData( )

    Assncrona Future getData( ) Observable getData( )

  • RELEITURA DE CONTRATOS

    Iterable Observer

    Obter o prximo T next( ) onNext( T )

    Sinalizar erro throws Exception( ) onError( Thowable )

    Saber se terminou hasNext( ) onComplete( )

    PULLED WAY

    PUSHED WAY

  • CONCEITOS BSICOS

    OBSERVABLE

    OBSERVER

    OPERATOR

    SCHEDULER

  • OBSERVABLE

    Representa o fluxo de dados (ou eventos, ou itens emitidos)

    Por padro, executa de forma sequencial (no concorrente)

    Repassa cada item emitido para um observador (callback)

    Pode ser associado ao conceito de source da Streams API do java8, porm seguindo push model quanto aos dados

  • CRIANDO OBSERVABLES (I)

    Observable source = Observable.just("GOOGLE", "APPLE", "MICROSOFT");

    source.subscribe(System.out::println);

    GOOGLEAPPLEMICROSOFT

    PROCESS FINISHED WITH EXIT CODE 0

  • CRIANDO OBSERVABLES (II)

    Observable.fromCallable(() -> RxJava is Awesome)

    .subscribe(System.out::println);

    List names = Arrays.asList("Banana", "Apple", "Orange");

    Observable.from(names).subscribe(System.out::println);

  • CRIANDO OBSERVABLES (III)

    Observable.interval(1, TimeUnit.SECONDS)

    .map(time -> "AT SECOND " + time)

    .subscribe(System.out::println);

    AT SECOND 0AT SECOND 1AT SECOND 2AT SECOND 3

    WARNING : estamos roubando aqui, se voc executar esse cdigo, no ver esse log !!!!

  • OBSERVER

    Consome o fluxo de dados

    Respeita o contrato no estilo pushed data

    o ponto no qual os erros flutuam : um erro que acontea durante uma operao interrompe a sequncia de emisses

    Callbacks sinalizam o trmino da sequncia

    Adies ao Observer Pattern do GOF

  • OBSERVER

    public interface Observer {

    }

    void onCompleted();

    void onError(Throwable e);

    void onNext(T data);

  • PIPELINE DE OPERAES

    Observable.from()

    .flatMap()

    .filter()

    .map()

    .observeOn()

    .subscribeOn()

    .subscribe();

    upstream sequence

    downstream sequence

  • Observable.zip( restApi.getAvaliableItems(), restApi.getRecommendedItems(clientId),

    new ItemsResultsZipper())

    .subscribeOn(Schedulers.io())

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(new Observer() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List items) { } });

    podemos fazer melhor ?

  • OPERADORES

    Funes que permitem manipular a sequncia de eventos observveis, sejam os itens emitidos, seja a prpria sequncia (ou mltiplas delas)

    Reactive Extensions define um enorme catlogo de operadores quanto semntica, em categorias bem definidas

  • CATEGORIA OPERADORES

    CRIAO just( ), from( ), range( ), interval( ), defer( )

    COMBINAO zip( ), merge( ), combineLatest( ), concat( )

    TRANSFORMAO map( ), flatMap( ), concatMap( )

    FILTRAGEM filter( ), take( ), skip( ), debounce( )

    MUITO MAIS ! cache( ), replay( ), retry( ), retryWhen( )

  • MARBLE DIAGRAMS

    A B C D E

    onNext( ) chamado cinco vezes

  • MARBLE DIAGRAMS

    A B C

    1 2 3 4 5

    x

    I

    onError( )

    onCompleted( )

  • MAP

    1 2 3 4 5

    A B C D E

    MAP { INT X -> CHAR Y }

  • FILTER

    1 2 3 4 5

    2 4

    FILTER { INT X -> INT Y}

  • MERGE

    1 3 5

    2 4

    1 2 3 4 5

    MERGE

    I

    I

    I

  • CONCAT

    1 3 5

    2 4

    1 3 5 2 4

    CONCAT

    I

    I

    I

  • AMB

    1 3 5

    2 4

    1 3 5

    AMB

    I

    I

    I

  • INTERVAL

    INTERVAL {}

    1 2 3 4 5

  • rxmarbles.comDisponvel como app Android

    http://rxmarbles.com

  • SCHEDULER

    Escalonador de trabalho entre threads distintas

    Abstrao em volta de Executors ( java.util.concurrent )

    Qualquer Observable pode ser produzido em um Scheduler e observado em outro

    Mecanismo fundamental para aplicaes mveis

  • Observable.range(1, 2) .map(i -> i * 2) .observeOn(Schedulers.io()) .doOnNext(i -> System.out.println( "Emitting " + i + " on thread " + threadName())) .observeOn(Schedulers.computation()) .map(i -> i * 10) .subscribe(i -> System.out.println( "Received " + i + " on thread " + threadName()));

    Emitting 2 on thread RxCachedThreadScheduler-1Received 20 on thread RxComputationThreadPool-3Emitting 4 on thread RxCachedThreadScheduler-1Received 40 on thread RxComputationThreadPool-3

    sleep(3000);

  • Observable.just("Google", "Apple", "Microsoft", "IBM") .subscribleOn(Schedulers.computation()) .subscribe(s -> System.out.println( "Received " + s + " on thread " + threadName()));

    Received Google on thread RxComputationThreadPool-1Received Apple on thread RxComputationThreadPool-1Received Microsoft on thread RxComputationThreadPool-1Received IBM on thread RxComputationThreadPool-1

    sleep(3000);

  • NUNCIAS SOBRE SCHEDULERS (I)

    Schedulers.io( ) encapsula um thread pool de tamanho varivel

    Schedulers.computation( ) encapsula um thread pool de tamanho fixo

    Operam sobre deamon threads

    So extensveis para encapsular threads importantes, como por exemplo a UI thread do Android ou do JavaFX

    Alguns factory methods de Observable j associam um scheduler sequncia (como interval( ) )

  • NUNCIAS SOBRE SCHEDULERS (II)

    subscribeOn( ) instrui o framework sobre em qual thread os itens sero emitidos para o consumidor

    observeOn( ) instrui o framework sobre quais schedulers podem operar nas etapas intermedirias do pipeline de operaes

    subscribeOn( ) em geral usado uma vez no pipeline

    observeOn( ) utilizado conforme a necesside de concorrncia nas etapas do pipeline

  • TRATAMENTO DE ERROS

    Evento terminal destri a sequncia. Period.

    Recuperao controlada via operadores onErrorResumeNext( ), onErrorReturn( ) e outros

    Sugesto : implemente um wrapper com o retorno de onError( throwable), isso ajudar no stacktrace em casos de erro

  • CONCEITOS AVANADOS

  • FLATMAP

    "Transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable

    The FlatMap operator transforms an Observable by applying a function that you specify to each item emitted by the source Observable, where that function returns an Observable that itself emits items. FlatMap then merges the emissions of these resulting Observables, emitting these merged results as its own sequence.

    This method is useful, for example, when you have an Observable that emits a series of items that themselves have Observable members or are in other ways transformable into Observables, so that you can create a new Observable that emits the complete collection of items emitted by the sub-Observables of these items. "

  • FLATTENING

    MAPPING

  • List companies = Arrays.asList("Google", "Apple", "Microsoft");

    List leaders = Arrays.asList("Larry", "Steve", "Bill");

    Observable obs = Observable.just(companies, leaders);

    Observable flat = obs.flatMap(strings -> Observable.from(strings));

    flat.subscribe(System.out::println);

    GoogleAppleMicrosoftLarrySteveBill

    flatMap( ) desmontou 2 sequncias de items e juntou individualmente os itens de cada sequncia em uma nica sequncia final

    mapeamento

  • MAIS SOBRE FLATMAP

    flatmap( ) o mecanismo padro para encadeamento de operaes assncronas

    flatma