0Pricing
Scala for Backend Engineering & Functional Programming · Aula

Projetando sistemas de atores

Aprenda a projetar e implementar hierarquias de atores, definir comportamentos de atores e enviar e receber mensagens.

Projetando sistemas de atores é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 2 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 3 aulas no total.

Criando sistemas de atores: introdução

Boas-vindas à Lição 2! Na lição anterior, aprendemos os fundamentos do Modelo de Atores do Akka. Agora, vamos nos aprofundar no design de sistemas de atores do Akka.

Um sistema de atores bem projetado é robusto, escalável e fácil de manter. Vamos explorar como estruturar seus atores, definir seus comportamentos e permitir que eles se comuniquem com eficiência.

Compreendendo as hierarquias de atores

Os atores do Akka são organizados em uma hierarquia semelhante a uma árvore, assim como um sistema de arquivos. Todo ator, exceto o ator 'raiz', tem um pai.

  • Relação pai-filho: um ator que cria outro ator torna-se seu pai.
  • Supervisão: essa hierarquia é essencial para a tolerância a falhas do Akka. Os pais são responsáveis por supervisionar seus filhos (veremos mais sobre isso na próxima lição!).
  • Endereçamento baseado em caminho: cada ator tem um caminho exclusivo, que representa sua posição na hierarquia, como /user/parentActor/childActor.

Configurando seu ActorSystem

O ActorSystem é o ponto de entrada para todas as aplicações Akka. Ele gerencia os recursos necessários aos atores, incluindo conjuntos de segmentos e agendadores.

Você o cria uma vez por aplicação e depois o utiliza para criar seus atores de nível superior. Ele funciona como o contêiner de toda a sua aplicação de atores.

Experimente executar este código simples para criar um ActorSystem:

import akka.actor.ActorSystem

object AkkaSystemApp {
  def main(args: Array[String]): Unit = {
    // Create an ActorSystem with a unique name
    val system = ActorSystem("MyFirstActorSystem")
    println("ActorSystem created: " + system.name)

    // Remember to terminate the system when done!
    system.terminate()
  }
}

Definindo o comportamento dos atores

O comportamento de um ator determina como ele reage a diferentes mensagens. Em Scala, você define isso estendendo o traço Actor e implementando o método receive.

  • O método receive é uma função parcial que associa mensagens recebidas a ações específicas.
  • Cada ator processa as mensagens uma por vez, sequencialmente, garantindo a segurança de threads para seu estado interno.

ActorRef: o endereço do ator

Você não interage diretamente com as instâncias dos atores. Em vez disso, envia mensagens para um ActorRef. Pense no ActorRef como o endereço postal de um ator.

  • Ele é uma referência que representa um ator específico dentro do sistema.
  • As mensagens enviadas para um ActorRef são colocadas na caixa de mensagens do ator.
  • Você obtém um ActorRef ao criar um ator usando actorOf.

Enviando mensagens aos atores

A principal forma de comunicação entre atores é o envio de mensagens. A maneira mais comum de enviar uma mensagem é usando o método ! (pronunciado 'tell').

receiverActorRef ! "Your message here"

O método tell é assíncrono e funciona no modelo de disparar e esquecer. Ele envia a mensagem e não espera uma resposta.

Vamos combinar a criação de um ator com o envio de mensagens para ele:

import akka.actor.{Actor, ActorRef, Props, ActorSystem}

// 1. Define the actor's behavior
class GreeterActor extends Actor {
  def receive = {
    case "hello" => println(s"Greeter: Hello from ${self.path.name}!")
    case msg: String => println(s"Greeter: Received message: '$msg'")
    case _ => println("Greeter: Received something unexpected!")
  }
}

object SimpleActorApp {
  def main(args: Array[String]): Unit = {
    // 2. Create the ActorSystem
    val system = ActorSystem("GreeterSystem")

    // 3. Create a top-level actor and get its ActorRef
    val greeter: ActorRef = system.actorOf(Props[GreeterActor], "myGreeter")
    
    // 4. Send messages to the actor using '!'
    greeter ! "hello"
    greeter ! "How are you doing today?"
    greeter ! 123 // This will match the _ case

    // Give actors time to process messages, then terminate
    Thread.sleep(1000)
    system.terminate()
  }
}

Criando atores filhos

Os atores podem criar outros atores, formando a hierarquia que discutimos. Um ator pai cria seus atores filhos usando context.actorOf.

  • context.actorOf: usado por um ator para criar seus filhos.
  • system.actorOf: usado pela aplicação para criar atores de nível superior (guardiões).

A criação de atores filhos ajuda a organizar o sistema, delegar tarefas e isolar falhas.

Comunicação entre pai e filho

Os atores se comunicam enviando mensagens para o ActorRef uns dos outros. Um ator filho pode obter o ActorRef de seu pai por meio de context.parent. Para responder ao remetente de uma mensagem, um ator pode usar sender().

Vamos ver um exemplo em que um pai cria um filho, diz a ele para realizar um trabalho e o filho informa quando termina:

import akka.actor.{Actor, ActorRef, Props, ActorSystem}
import scala.concurrent.ExecutionContext.Implicits.global

// Child Actor Definition: Does work and replies to sender
class ChildActor extends Actor {
  def receive = {
    case "work" =>
      println(s"ChildActor (${self.path.name}): Doing work from ${sender().path.name}")
      sender() ! "done" // Reply 'done' to the sender (parent)
  }
}

// Parent Actor Definition: Creates child, sends work, receives reply
class ParentActor extends Actor {
  // Create a child actor when the parent starts
  val child: ActorRef = context.actorOf(Props[ChildActor], "myChild")

  def receive = {
    case "start" =>
      println("ParentActor: Kicking off child's work.")
      child ! "work" // Tell the child to do 'work'
    case "done" =>
      println(s"ParentActor: Child ${sender().path.name} reported 'done'.")
      context.stop(child) // Stop the child actor
      context.stop(self)   // Stop the parent actor
  }
}

object HierarchyApp {
  def main(args: Array[String]): Unit = {
    val system = ActorSystem("HierarchySystem")
    val parent: ActorRef = system.actorOf(Props[ParentActor], "parentActor")
    parent ! "start" // Start the interaction

    // Wait for the system to terminate (actors will stop themselves)
    system.whenTerminated.onComplete(_ => println("ActorSystem terminated."))
  }
}

Interrompendo atores de forma adequada

Os atores devem ser interrompidos de forma adequada quando não forem mais necessários, para que os recursos sejam liberados. Você pode interromper um ator de algumas maneiras:

  • context.stop(self): o ator interrompe a si mesmo.
  • context.stop(childRef): um pai interrompe um de seus filhos.
  • system.stop(actorRef): usado para atores de nível superior, embora normalmente você interrompa o sistema inteiro.

Quando um ator é interrompido, ele processa todas as mensagens em sua caixa de mensagens antes de terminar. Seus filhos também são interrompidos recursivamente.

Verificação rápida: design de atores

Considere o seguinte trecho de código de um ator do Akka. Qual é a maneira correta de MyChildActor enviar uma mensagem de volta ao pai que o criou, MyParentActor, se MyParentActor foi o remetente da mensagem inicial de 'request'?

Recapitulação: criando sistemas de atores

Excelente trabalho! Nesta lição, abordamos aspectos importantes do design de sistemas de atores do Akka:

  • Os atores são organizados em hierarquias, essenciais para a supervisão e a estrutura.
  • O ActorSystem é o ponto de entrada da sua aplicação para o Akka.
  • Você define o comportamento dos atores usando o método receive.
  • O ActorRef é o endereço usado para enviar mensagens.
  • Os atores se comunicam de forma assíncrona usando o método ! (tell).
  • Os pais criam filhos com context.actorOf, e os filhos podem responder usando sender().
  • Os atores podem ser interrompidos de forma adequada usando context.stop().

Em seguida, vamos nos aprofundar nas poderosas estratégias de supervisão do Akka e em como lidar adequadamente com falhas!

Perguntas Frequentes

A aula “Projetando sistemas de atores” é grátis?

Sim — o texto completo de “Projetando sistemas de atores” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 3 aulas no total.

O que vou aprender em “Projetando sistemas de atores”?

Aprenda a projetar e implementar hierarquias de atores, definir comportamentos de atores e enviar e receber mensagens. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?

Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 3.

Quanto tempo leva a aula “Projetando sistemas de atores”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?

Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fundamentos do modelo de atores do Akka
  2. Projetando sistemas de atores
  3. Supervisão e tolerância a falhas
← Voltar para Scala for Backend Engineering & Functional Programming