I have a scenario where I need to provide a Behavior of a specific type. This Behavior also needs to handle events that are published on the Event Stream. So say the specific type is:
case class DoSomething(i: Int)
and I then need to implement a function to return a Behavior to handle this type of message:
def foo(): Behavior[DoSomething]
I then also need to handle the following message on the event stream:
case class PublishedEvent(str: String)
The only solution I came up with was to spawn another actor from within my DoSomething behavior and then forward messages to it:
sealed trait Command
case class Command1(str: String) extends Command
case class Command2(str: String) extends Command
def foo(): Behavior[DoSomething] = Behaviors.setup { context =>
val actor = context.spawnAnonymous[Command](Behaviors.setup { context =>
context.system.eventStream ! EventStream.Subscribe(context.messageAdapter {
case PublishedEvent(str) => Command2(str)
})
Behaviors.receiveMessage {
case Command1(str) =>
println("Received Command1: " + str)
Behaviors.same
case Command2(str) =>
println("Received Command1: " + str)
Behaviors.same
}
})
Behaviors.receiveMessage {
case DoSomething(i) =>
actor ! Command1(i.toString)
Behaviors.same
}
}
My question is is there any means of avoiding spawning a new actor and doing it all from within the same actor? i.e. Is there a way I can map a Behavior[Command]
to a Behavior[DoSomething]
?
The docs (as well as the signature) indicate that
transformMessages
onBehavior
would work, provided that the externally sent messages map 1:1 to internal messages:i.e. an actor materialized with
Behavior[T].transformMessages[Outer] { ??? }
will yield anActorRef[Outer]
In this case, the internal commands are invisible outside of their scope. The main potential drawback I see (beyond the slight ickiness of bringing a
PartialFunction
into typed) is that within an actor withBehavior[Internal]
, you can't get theActorRef
for actor's external "personality", unless you have something crazy likeIt's worth noting that in the case where the internal messages are under your control, the 1:1 restriction can be worked around.