Skip to content

Instantly share code, notes, and snippets.

@josdirksen
Created November 15, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josdirksen/9aefdbd19e1cee0b99f6 to your computer and use it in GitHub Desktop.
Save josdirksen/9aefdbd19e1cee0b99f6 to your computer and use it in GitHub Desktop.
import AkkaTypedReceptionist.FirstService.{FirstServiceMsg1, FirstServiceMsg}
import AkkaTypedReceptionist.SecondService.{SecondServiceMsg1, SecondServiceMsg}
import AkkaTypedReceptionist.SenderService.{sendMessage, registerAddresses, SenderMsg}
import akka.typed.{ActorSystem, Props, ActorRef, PreStart}
import akka.typed.ScalaDSL._
import akka.typed.patterns.Receptionist
import akka.typed.patterns.Receptionist._
object AkkaTypedReceptionist extends App {
/**
* Simple service and protocol. Does nothing special, just print out
* the received message.
*/
object FirstService {
sealed trait FirstServiceMsg
final case class FirstServiceMsg1(msg: String) extends FirstServiceMsg
val behavior = Static[FirstServiceMsg] {
case msg:FirstServiceMsg => println("First Service Receiver: " + msg)
}
}
/**
* Another simple service and protocol. Does nothing special, just print out
* the received message.
*/
object SecondService {
sealed trait SecondServiceMsg
final case class SecondServiceMsg1(msg: String) extends SecondServiceMsg
val behavior = Static[SecondServiceMsg] {
case msg:SecondServiceMsg => println("Second Service Receiver: " + msg)
}
}
object SenderService {
sealed trait SenderMsg
final case class registerAddresses(firstServices: Set[ActorRef[FirstServiceMsg]], secondServices: Set[ActorRef[SecondServiceMsg]]) extends SenderMsg
final case class sendMessage(msg: String) extends SenderMsg
val behavior = Total[SenderMsg] {
case registerAddresses(firstRefs, secondRefs) => {
Static {
case sendMessage(msg) => {
firstRefs.foreach(_ ! FirstServiceMsg1(msg))
secondRefs.foreach(_ ! SecondServiceMsg1(msg))
}
}
}
case _ => Same
}
}
val scenario2 = {
Full[Unit] {
case Sig(ctx, PreStart) => {
val receptionist = ctx.spawn(Props(Receptionist.behavior), "receptionist");
// register three actors that can work with the FirstServiceMsg protocol
val service1a = ctx.spawn(Props(FirstService.behavior), "service1a")
val service1b = ctx.spawn(Props(FirstService.behavior), "service1b")
val service1c = ctx.spawn(Props(FirstService.behavior), "service1c")
// register three actors that can work with the SecondServiceMsg protocol
val service2a = ctx.spawn(Props(SecondService.behavior), "service2a")
val service2b = ctx.spawn(Props(SecondService.behavior), "service2b")
val service2c = ctx.spawn(Props(SecondService.behavior), "service2c")
// and the actor that will eventually send messages
val sender = ctx.spawn(Props(SenderService.behavior),"sender")
// define the service keys we'll use for registering
val serviceKey1 = new ServiceKey[FirstServiceMsg] {}
val serviceKey2 = new ServiceKey[SecondServiceMsg] {}
// register the services with the receptionise
val responseWrapperFirst = ctx.spawnAdapter[Registered[FirstServiceMsg]] {case _ =>}
val responseWrapperSecond = ctx.spawnAdapter[Registered[SecondServiceMsg]] {case _ =>}
receptionist ! Register(serviceKey1, service1a)(responseWrapperFirst)
receptionist ! Register(serviceKey1, service1b)(responseWrapperFirst)
receptionist ! Register(serviceKey1, service1c)(responseWrapperFirst)
receptionist ! Register(serviceKey2, service2a)(responseWrapperSecond)
receptionist ! Register(serviceKey2, service2b)(responseWrapperSecond)
receptionist ! Register(serviceKey2, service2c)(responseWrapperSecond)
// as a client we can now ask the receptionist to give us the actor references for services
// that implement a specific protocol. We pass the result to the sender service. Ugly way
// for now, but more to demonstrate how it works.
val getListingWrapper = ctx.spawnAdapter[Listing[FirstServiceMsg]] {
case firsts : Listing[FirstServiceMsg] => {
val secondWrapper = ctx.spawnAdapter[Listing[SecondServiceMsg]] {
case seconds : Listing[SecondServiceMsg] => {
sender ! registerAddresses(firsts.addresses, seconds.addresses)
}
}
receptionist ! Find[SecondServiceMsg](serviceKey2)(secondWrapper)
}
}
// get message from the first lookup, and pass it to the adapter, which will look up the
// second
receptionist ! Find[FirstServiceMsg](serviceKey1)(getListingWrapper)
// now wait a bit to make sure that through the receptionist we get a list of target actorrefs
Thread.sleep(200)
// these are sent to all the registered service implementations
sender ! sendMessage("Hello1")
sender ! sendMessage("Hello2")
Same
}
}
}
val scenario1Actor = ActorSystem("Root", Props(scenario2))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment