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

Akka - Uma plataforma para o desenvolvimento de...

Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM

Uma descrição da plataforma Akka, descrição do que são atores, e outras funcionalidades providas, com exemplos para Java.

Daniel Capo Sobral

June 04, 2012
Tweet

More Decks by Daniel Capo Sobral

Other Decks in Programming

Transcript

  1. Akka Uma plataforma para o desenvolvimento de sistemas concorrentes e

    distribuídos para a JVM • Daniel Capó Sobral • Consultor pela Tecnisys • Programador e Sysadmin • Ex-committer FreeBSD • Aficionado por Scala
  2. Akka Uma plataforma para o desenvolvimento de sistemas concorrentes e

    distribuídos para a JVM Conheça Akka, uma plataforma para o JVM para desenvolvimento de sistemas concorrentes e/ou distribuídos através do paradigma de Atores. Descreveremos o paradigma de atores, suas vantagens e desvantagens, e mostraremos exemplos da API em Java e em Scala, com execução local e distribuída, memória transacional e tolerância a falhas.
  3. Conteúdo • O que é Akka? • Para que serve?

    • O que são atores? Objetivos Principais • Ensinar Akka • Ensinar programação com atores • Mostrar todos os módulos de Akka Não é tema
  4. Um componente do Typesafe Stack? • A Typesafe foi fundada

    em 2011 pelos criadores da linguagem de programação Scala e do middleware Akka. • O Typesafe Stack contém Scala, Akka e ferramentas de desenvolvimento, tudo open source. • A Typesafe Subscription provê suporte comercial.
  5. Uma solução de: • Atores • STM • Agentes •

    Dataflow Concorrência Escalabilidade Tolerância à Falhas
  6. Uma solução de: Concorrência • Vertical • Atores • Horizontal

    • Atores Remotos • Gestão de Cluster Escalabilidade Tolerância à Falhas
  7. Uma solução de: Concorrência Escalabilidade • Supervisão de Atores •

    Todos Por Um • Cada Um Por Si • “Deixe falhar” Tolerância à Falhas
  8. Atores • Popularizou o conceito • 9 9s de disponibilidade

    Erlang • Atores como prova de conceito Scala • Novo design • Solução completa Akka
  9. Objetos vs Atores • Públicos • Privados Métodos • Rascunho

    • Estático • Dinâmico Estado • Orientado a eventos Thread
  10. Fatos sobre Atores • Assíncronos • Threads próprios Orientados à

    eventos • Caixa de mensagens • Não compartilham estado! Comunicação via mensagens • Atores não são threads • Aproximadamente 600 bytes Baratos
  11. Definindo um Ator - Java public class SampleUntypedActor extends UntypedActor

    { public void onReceive(Object message) throws Exception { if (message instanceof String) EventHandler.info(this, String.format("Received String message: %s", message)); else throw new IllegalArgumentException("Unknown message: " + message); } }
  12. Criando um Ator - Java import static akka.actor.Actors.*; ActorRef myActor

    = actorOf(SampleUntypedActor.class); myActor.start(); // Construtor com parâmetros ActorRef actor = actorOf(new UntypedActorFactory() { public UntypedActor create() { return new MyUntypedActor("service:name", 5); } }).start();
  13. ActorRef vs Actor • Serializável • Remote-aware Portabilidade • Actor

    é membro privado de ActorRef Opacidade • Actor this • ActorRef self this vs self
  14. Ciclo de Vida New • Não processa mensagens Started •

    Iniciado com “start” • Processa mensagens Shutdown • Iniciado com “exit” ou “stop” • Não pode fazer nada
  15. Enviando uma mensagem • actor.sendOneWay("Hello"); Envie e esqueça • actor.sendOneWay("Hello",

    getContext()); Envie, com remetente • Object result = actorRef.sendRequestReply("Hello", getContext(), 1000); Envie, talvez receba resposta (ou exceção) • Future future = actorRef.sendRequestReplyFuture("Hello", getContext(), 1000); Envie, receba futuro
  16. Futuros interface Future<T> { void await(); boolean isCompleted(); boolean isExpired();

    long timeoutInNanos(); Option<T> result(); Option<Throwable> exception(); Future<T> onComplete(Procedure<Future<T>> procedure); }
  17. Usando Futuros - Java Future future = actorRef.sendRequestReplyFuture("Hello", getContext(), 1000);

    future.await(); if (future.isCompleted()) { Option resultOption = future.result(); if (resultOption.isDefined()) { Object result = resultOption.get(); ... } ... // whatever }
  18. Respondendo ao Remetente - Java public void onReceive(Object message) throws

    Exception { if (message instanceof String) { String msg = (String)message; if (msg.equals("Hello") && getContext().getSenderFuture().isDefined()) { // Reply to original sender of message using the channel getContext().channel().sendOneWay(msg + " from " + getContext().getUuid()); } } }
  19. Respondendo Mensagem - Java public void onReceive(Object message) throws Exception

    { if (message instanceof String) { String msg = (String)message; if (msg.equals("Hello")) { if (getContext().replySafe(msg + " from " + getContext().getUuid())) ... // success else ... // handle failure } } }
  20. Akka em Scala • router.tell(new Work(arg, nrOfElements), getContext()); • router

    ! Work(arg, nrOfElements) Concisão • val a = actorOf(new MyActor(..)).start() Parâmetros “by-name” • Ver exemplo de concisão acima! Parâmetros implícitos
  21. Akka em Scala • case class Work(arg: Int, nrOfElements: Int)

    • Coleções imutáveis por default • Estruturas de dados persistentes Melhor suporte a imutabilidade • case Work(arg, n) => // do stuff Pattern matching
  22. Typed Actors • Requer Interface + Implementation POJO -> TypedActors

    • AspectWerkz Proxy AOP • Métodos viram mensagens assíncronas! Objetos -> Atores
  23. Agentes Inspirado nos Agentes de Clojure • Uma modificação de

    cada vez • Modificações de cada origem processadas em ordem Modificações Assíncronas • Toma parte em transações Integrado ao STM • Valor “atual” após todas modificações enfileiradas Futuros
  24. Agentes - Scala • val agent = Agent(5) • agent.close()

    Criando e Parando • agent send 7 • agent send (_ + 1) Alterando • val result = agent() • val result = agent.future.await.result.get Lendo
  25. STM - Java final Ref<Integer> ref = new Ref<Integer>(0); public

    int counter() { return new Atomic<Integer>() { public Integer atomically() { int inc = ref.get() + 1; ref.set(inc); return inc; } }.execute(); }
  26. Dataflow • Mesmo resultado todas as vezes • Baseado em

    futuros • Scala Delimited Continuations Concorrência Determinística Derivado da linguagem Oz • Exceções, data/hora, números aleatórios, etc Nada de efeitos colaterais!
  27. Dataflow - Scala • val x = Promise[Int]() Declarar variável

    dataflow • flow { ... x() ... } Usar valor • flow { ... x << 5 ... } Assinalar valor • flow { ... x << y ... } Assinalar a uma outra variável
  28. Atores Remotos - Java // server code class HelloWorldActor extends

    UntypedActor { public void onReceive(Object msg) { getContext().replySafe(msg + " World"); } } remote().start("localhost", 9999).register( "hello-service", actorOf(HelloWorldActor.class)); // client code ActorRef actor = remote().actorFor( "hello-service", "localhost", 9999); Object res = actor.sendRequestReply("Hello");
  29. Tolerância à Falhas • Não se proteja de exceções •

    Deixe outro lidar com o problema Deixe falhar... • Erlang OTP • Proteção em Profundidade Supervisores • OneForOne • AllForOne Estratégias de Supervisão
  30. Tolerância à Falhas • Recuperável • Não-recuperável Estado • Antes

    da reinicialização • Depois da reinicialização Ganchos de reinicialização • Permanente • Temporário Ciclo de vida
  31. Só isso? • getContext().forward(message, getContext()); Encaminhando mensagens para outro Ator

    • become(scatter); • actor ! HotSwap( self => { case message => self.reply("hotswapped body") }) Alterando o comportamento de um ator
  32. Só isso? • Por eventos • Por thread • Eventos

    priorizados • Eventos com work-stealing Dispatcher • Dispatcher (roteador, não módulo) • Load balance • Actor pool Routing • Usados por atores, agentes, dataflow e outros componentes Futuros