Actor Registry - laforge49/Asynchronous-Functional-Programming GitHub Wiki
Unlike Factory objects, which have a FactoryId, Actor objects do not have an id. But if the Actor implements IdActor, then the actor has an ActorId and can be registered. And as a convenience, Id_Actor can be used:
class Id_Actor extends Actor with IdActor
The Greeter class extends Id_Actor, which allows its instances to be registered:
case class Greet()
class Greeter
extends Id_Actor {
bind(classOf[Greet], greet)
def greet(msg: AnyRef, rf: Any => Unit) {
println("Hello world!")
rf(null)
}
}
Here is the GreeterFactory, which has a factory id of "greeter":
class GreeterFactory
extends Factory(new FactoryId("greeter")) {
override def instantiate = new Greeter
}
Now we want a SystemServices object which includes both Factory and Actor registration, and we also want to register GreeterFactory. This can all be done with a single component factory:
class SomeComponentFactory
extends ComponentFactory {
addDependency(classOf[FactoryRegistryComponentFactory])
addDependency(classOf[ActorRegistryComponentFactory])
override def configure(compositeFactory: Factory) {
FactoryRegistryComponentFactory.register(compositeFactory, new GreeterFactory)
}
}
Here is the test code which creates the system services composite that we need and which runs two tests using a Driver object:
val systemServices = SystemServices(new SomeComponentFactory)
try {
val driver = new Driver
driver.setExchangeMessenger(systemServices.newSyncMailbox)
Future(driver, DoIt1())
Future(driver, DoIt2())
} finally {
systemServices.close
}
The first test will create two Greeter objects with Id's of "a" and "b", and register them. The second test unregisters actor "a" and then passes a Greet message to actor "b".
case class DoIt1()
case class DoIt2()
class Driver
extends Actor {
bind(classOf[DoIt1], doit1)
bind(classOf[DoIt2], doit2)
def doit1(msg: AnyRef, rf: Any => Unit) {
val chain = new Chain()
chain.op(systemServices, Instantiate(FactoryId("greeter"), null), "a")
chain.op(systemServices, Unit => {
val a = chain("a").asInstanceOf[Id_Actor]
a.id(ActorId("a"))
Register(a)
})
chain.op(systemServices, Instantiate(FactoryId("greeter"), null), "b")
chain.op(systemServices, Unit => {
val b = chain("b").asInstanceOf[Id_Actor]
b.id(ActorId("b"))
Register(b)
})
systemServices(chain)(rf)
}
def doit2(msg: AnyRef, rf: Any => Unit) {
val chain = new Chain()
chain.op(systemServices, Unregister(ActorId("a")))
chain.op(systemServices, ResolveName(ActorId("b"), null), "b")
chain.op(chain("b"), Greet())
systemServices(chain)(rf)
}
}