-
Messages and Behaviorakka & pekko/actors 2023. 7. 17. 13:23
ref ! s"Forwards: $message"
1. messages can be of any type
- messages must be IMMUTABLE
- messages must be SERIALIZABLE (in practice use case class and case objects
import akka.actor.{Actor, ActorSystem, Props} object TestActor { def main(args: Array[String]): Unit = { val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo") class SimpleActor extends Actor { override def receive: Receive = { case message: String => println(s"String message: $message") case number: Int => println(s"Int number: $number") } } val simpleActor = actorSystem.actorOf(Props[SimpleActor], "simpleActor") simpleActor ! "A" simpleActor ! 1 } }
2. actors have information about their context and about themselves
- context.self == `this` in OOP
- context.self 대신 self (aliased) 사용 가능
import akka.actor.{Actor, ActorSystem, Props} object TestActor { def main(args: Array[String]): Unit = { val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo") class SimpleActor extends Actor { override def receive: Receive = { case message: String => println(s"[${context.self}] String message: $message") self ! message.toInt case number: Int => println(s"[${self.path}] Int number: $number") } } val simpleActor = actorSystem.actorOf(Props[SimpleActor], "simpleActor") simpleActor ! "1" } }
결과
[Actor[akka://actorCapabilitiesDemo/user/simpleActor#969381549]] String message: 1 [akka://actorCapabilitiesDemo/user/simpleActor] Int number: 1
3. actors can REPLY to messages
- context.sender() 활용
package com.github.windbird123 import akka.actor.{Actor, ActorRef, ActorSystem, Props} object TestActor { def main(args: Array[String]): Unit = { val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo") class SimpleActor extends Actor { override def receive: Receive = { case "Hello" => println(s"[${context.sender()} --> $self] Hello") case message: String => println(s"[${context.sender()} --> $self] String message: $message") context.sender() ! "Hello" case SayHiTo(ref) => println(s"[${context.sender()} --> $self] SayHiTo message") ref ! "Hi" } } val alice = actorSystem.actorOf(Props[SimpleActor], "alice") val bob = actorSystem.actorOf(Props[SimpleActor], "bob") case class SayHiTo(ref: ActorRef) // Actor.noSender --> alice --> bob(reply) --> alice alice ! SayHiTo(bob) } }
결과
[Actor[akka://actorCapabilitiesDemo/deadLetters] --> Actor[akka://actorCapabilitiesDemo/user/alice#2067059408]] SayHiTo message [Actor[akka://actorCapabilitiesDemo/user/alice#2067059408] --> Actor[akka://actorCapabilitiesDemo/user/bob#538084463]] String message: Hi [Actor[akka://actorCapabilitiesDemo/user/bob#538084463] --> Actor[akka://actorCapabilitiesDemo/user/alice#2067059408]] Hello
4. dead letters (Actor.noSender)
import akka.actor.{Actor, ActorSystem, Props} object TestActor { def main(args: Array[String]): Unit = { val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo") class SimpleActor extends Actor { override def receive: Receive = { case message: String => println(s"[${context.sender()} --> $self] String message: $message") } } val alice = actorSystem.actorOf(Props[SimpleActor], "alice") alice ! "Hi" // who is a sender ? } }
결과
[Actor[akka://actorCapabilitiesDemo/deadLetters] --> Actor[akka://actorCapabilitiesDemo/user/alice#906235305]] String message: Hi
5. forwarding messages
- deadLetters -> A -> B
- forwarding: sending a message with the ORIGINAL sender
object TestActor { def main(args: Array[String]): Unit = { val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo") case class ForwardMessage(message: String, ref: ActorRef) class SimpleActor extends Actor { override def receive: Receive = { case message: String => println(s"[${context.sender()} --> $self] String message: $message") case ForwardMessage(message, ref) => println(s"[${context.sender()} --> $self] String message: $message") ref forward s"Forwards: $message" } } val A = actorSystem.actorOf(Props[SimpleActor], "A") val B = actorSystem.actorOf(Props[SimpleActor], "B") // Actor.noSender (ForwardMessage) -> A (Hi) -> B A ! ForwardMessage("Hi", B) } }
결과
[Actor[akka://actorCapabilitiesDemo/deadLetters] --> Actor[akka://actorCapabilitiesDemo/user/A#130061245]] String message: Hi [Actor[akka://actorCapabilitiesDemo/deadLetters] --> Actor[akka://actorCapabilitiesDemo/user/B#1295696439]] String message: Forwards: Hi
참고
아래처럼 forward 대신에 tell(!) 로 코드를 변경했을 때
// ref forward s"Forwards: $message" ref ! s"Forwards: $message"
결과는 다음과 같이 ORIGINAL sender 대신에, 두번째 로그에서 바로 직전의 sender(/user/A) 가 로깅된다.
[Actor[akka://actorCapabilitiesDemo/deadLetters] --> Actor[akka://actorCapabilitiesDemo/user/A#1641879570]] String message: Hi [Actor[akka://actorCapabilitiesDemo/user/A#1641879570] --> Actor[akka://actorCapabilitiesDemo/user/B#1749142701]] String message: Forwards: Hi
'akka & pekko > actors' 카테고리의 다른 글
Akka Logging (0) 2023.07.17 Child Actor (0) 2023.07.17 Behavior control (become / unbecome) (0) 2023.07.17 Actor 생성 (0) 2023.07.17 akka actors 소개 (0) 2023.07.17