I am starting to dive into AKKA/Event Bus and related...
I created a small test actor as follows:
class TestActor extends Actor with ClassLogger{
@throws[Exception](classOf[Exception])
override def preStart(): Unit = {
context.system.eventStream.subscribe(context.self, classOf[FormFieldValue])
}
override def receive = {
case (v: FormFieldValue) => logger.info("Value received: " + v.fieldValue)
case _ => logger.info("Something unknown")
}
}
and trying to publish an event from another part of an application:
system.eventStream.publish(updatedValue)
Everything compiles and works as it used to, and nothing been logged. Basically, the actor is not been called.
Now, I also tried to create a module that will register all the subscribers, like so:
class EventsRegistry @Inject()(system: ActorSystem) extends AbstractModule {
override def configure(): Unit = {
val testListeener = system.actorOf(Props(classOf[TestActor]))
system.eventStream.subscribe(testListeener, classOf[FormFieldValue])
}
}
And configured the module in application.conf:
play.modules.enabled += "events.modules.EventsRegistry"
and removed preStart from Actor.
And now I am getting an error:
lay.api.PlayException: No valid constructors[Module [events.modules.EventsRegistry] cannot be instantiated.]
What am I doing wrong?
Update the only way I got that working is by setting up subscriber in Global#onStart:
override def onStart(app: play.api.Application) {
val testListeener = Akka.system.actorOf(Props(classOf[TestActor]))
Akka.system.eventStream.subscribe(testListeener, classOf[FormFieldValue])
}
But usage of GlobalSettings is deprecated....
To make it work you need to decouple the Registry and the Module.
package actors
import akka.actor._
import com.google.inject._
import play.api.inject.ApplicationLifecycle
import scala.concurrent.Future
case class FormFieldValue(fieldValue: String)
class TestActor extends Actor with ActorLogging {
@throws[Exception](classOf[Exception])
override def preStart(): Unit = {
context.system.eventStream.subscribe(context.self, classOf[FormFieldValue])
super.preStart()
}
@throws[Exception](classOf[Exception])
override def postStop(): Unit = {
context.system.eventStream.unsubscribe(context.self)
super.postStop()
}
override def receive = {
case (v: FormFieldValue) => log.info("Value received: " + v.fieldValue)
case _ => log.info("Something unknown")
}
}
@Singleton
class EventBusLifeCycle @Inject()(system: ActorSystem, lifecycle: ApplicationLifecycle) {
val testListener = system.actorOf(Props(classOf[TestActor]))
lifecycle.addStopHook { () =>
Future.successful(system.stop(testListener))
}
}
class EventBusModule extends AbstractModule {
def configure() = {
bind(classOf[EventBusLifeCycle]).asEagerSingleton()
}
}
And register the module in application.conf
play.modules.enabled += "actors.EventBusModule"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.