scala - tiempo - Play 2.4: Programe una tarea recurrente al inicio de la aplicación con inyección de dependencia
tareas repetitivas en project (1)
Necesito programar una tarea recurrente en el inicio de la aplicación, la tarea en sí misma es muy simple, solo envíe a la aplicación una llamada HTTP de "se olvide y se olvide". No soy un experto en juegos, compro que asumiría que la solución directa sería algo así como usar play.api.libs.concurrent.Akka.system.schedule
en Global.onStart
. Desde Play 2.4, Global
configuración Global
está algo obsoleta a favor de la nueva Guice DI. Hackeando el consejo de la documentación DI no pude encontrar una buena solución para este problema. Lo mejor que logré es escribir un contenedor sobre GuiceApplicationLoader
llamando a una implementación personalizada de BuiltInComponentsFromContext
, pero en este caso no puedo usar la inyección para obtener WSClient
. ¿Cuál es la mejor manera de reescribir algo como esto con Play 2.4:
object Global extends GlobalSettings {
override def onStart(app: Application) = {
Akka.system.schedule(2.hours, 2.hours, theTask)
}
}
Actualización : esto ahora está mejor documentado para Play 2.6: https://www.playframework.com/documentation/2.6.x/ScheduledTasks
Puede resolver esto creando un módulo como este (atención a los comentarios del código):
package tasks
import javax.inject.{Singleton, Inject}
import akka.actor.ActorSystem
import com.google.inject.AbstractModule
import play.api.inject.ApplicationLifecycle
// Using the default ExecutionContext, but you can configure
// your own as described here:
// https://www.playframework.com/documentation/2.4.x/ThreadPools
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.Future
import scala.concurrent.duration._
class MyRecurrentTaskModule extends AbstractModule {
override def configure() = {
// binding the RecurrentTask as a eager singleton will force
// its initialization even if RecurrentTask is not injected in
// any other object. In other words, it will starts with when
// your application starts.
bind(classOf[RecurrentTask]).asEagerSingleton()
}
}
@Singleton
class RecurrentTask @Inject() (actorSystem: ActorSystem, lifecycle: ApplicationLifecycle) {
// Just scheduling your task using the injected ActorSystem
actorSystem.scheduler.schedule(1.second, 1.second) {
println("I''m running...")
}
// This is necessary to avoid thread leaks, specially if you are
// using a custom ExecutionContext
lifecycle.addStopHook{ () =>
Future.successful(actorSystem.shutdown())
}
}
Después de eso, debe habilitar este módulo agregando la siguiente línea en su archivo conf/application.conf
:
play.modules.enabled += "tasks.MyRecurrentTaskModule"
Luego, solo inicie su aplicación, active una solicitud y verá que la tarea programada se ejecutará cada segundo.
Referencias
- Descripción de los grupos de hilos de reproducción
- Jugar a Runtime Dependency Injection para Scala
- Integrando con Akka
Preguntas relacionadas