Вы можете запустить своих актеров в загрузочном файле akka или в вашем собственном ServletContextListener, чтобы они запускались без привязки к сервлету.Затем вы можете искать их в реестре akka.
Actor.registry.actorFor[MyActor] foreach { _ !! (("Run",id), 10000) }
Кроме того, в настоящий момент нет реальной интеграции akka со скалатрой.Так что до сих пор лучшее, что вы можете сделать, это использовать блокировку запросов к группе актеров.
Я не уверен, но я бы не стал вызывать актера для каждого запроса, а имел бы пул актеров виджетовкоторые вы можете отправить эти запросы.Если вы используете иерархию супервизора, то вы можете использовать супервизор для изменения размера пула, если он слишком большой или слишком маленький.
class MyContextListener extends ServletContextListener {
def contextInitialized(sce: ServletContextEvent) {
val factory = SupervisorFactory(
SupervisorConfig(
OneForOneStrategy(List(classOf[Exception]), 3, 1000),
Supervise(actorOf[WidgetPoolSupervisor], Permanent)
}
def contextDestroyed(sce: ServletContextEvent) {
Actor.registry.shutdownAll()
}
}
class WidgetPoolSupervisor extends Actor {
self.faultHandler = OneForOneStrategy(List(classOf[Exception]), 3, 1000)
override def preStart() {
(1 to 5) foreach { _ =>
self.spawnLink[MyWidgetProcessor]
}
Scheduler.schedule(self, 'checkPoolSize, 5, 5, TimeUnit.MINUTES)
}
protected def receive = {
case 'checkPoolSize => {
//implement logic that checks how quick the actors respond and if
//it takes to long add some actors to the pool.
//as a bonus you can keep downsizing the actor pool until it reaches 1
//or until the message starts returning too late.
}
}
}
class ScalatraApp extends ScalatraServlet {
get("/run/:id") {
// the !! construct should not appear anywhere else in your code except
// in the scalatra action. You don't want to block anywhere else, but in a
// scalatra action it's ok as the web request itself is synchronous too and needs to
// to wait for the full response to have come back anyway.
Actor.registry.actorFor[MyWidgetProcessor] foreach {
_ !! ((Run, id), 10000)
} getOrElse {
throw new HeyIExpectedAResultException()
}
}
}
Пожалуйста, рассматривайте приведенный выше код как псевдокод, который выглядит как scalaЯ просто хотел проиллюстрировать концепцию.