Created
November 15, 2015 14:05
-
-
Save josdirksen/9aefdbd19e1cee0b99f6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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