Play Framework 2.0 планирует актер Акка при запуске сервера
У меня есть аккер Акка, который проверяет случайные данные и вносит в него некоторые изменения на основе данных, показывающих время и обновляющих его. В настоящее время я использую этот код внутри контроллера:
static ActorRef instance = Akka.system().actorOf(new Props(ValidateAndChangeIt.class));
static {
Akka.system().scheduler().schedule(
Duration.Zero(),
Duration.create(5, TimeUnit.MINUTES),
instance, "VALIDATE"
);
}
Проблема с использованием этого внутри контроллера заключается в том, что кто-то должен получить доступ к странице, обработанной этим контроллером, для запуска актера, и если этого не произойдет, все будет приостановлено.
Есть ли способ сделать это при запуске сервера? Я действительно не знаю, как это происходит, если актер генерирует исключение. Остановит ли он будущие графики или продолжит? Если это не так, есть ли способ сделать перераспределение актера в случае сбоя или ошибки?
Ответы
Ответ 1
Для запуска кода при запуске сервера просмотрите Глобальный объект: переместите код с вашего контроллера на метод onStart()
public class Global extends GlobalSettings {
@Override
public void onStart(Application app) {
ActorRef instance = Akka.system().actorOf(new Props(ValidateAndChangeIt.class));
Akka.system().scheduler().schedule(
Duration.Zero(),
Duration.create(5, TimeUnit.MINUTES),
instance, "VALIDATE"
);
}
}
Ответ 2
Play Framework обеспечивает способ, с помощью которого планирование задания может быть выполнено в Global.java
без явного вызова его.
public class Global extends GlobalSettings {
private Cancellable scheduler;
@Override
public void onStart(Application app) {
super.onStart(app);
schedule();
}
@Override
public void onStop(Application app) {
//Stop the scheduler
if (scheduler != null) {
scheduler.cancel();
this.scheduler = null;
}
}
private void schedule() {
try {
ActorRef helloActor = Akka.system().actorOf(new Props(HelloActor.class));
scheduler = Akka.system().scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay 0 milliseconds
Duration.create(30, TimeUnit.MINUTES), //Frequency 30 minutes
helloActor,
"tick",
Akka.system().dispatcher(), null);
}catch (IllegalStateException e){
Logger.error("Error caused by reloading application", e);
}catch (Exception e) {
Logger.error("", e);
}
}
}
И создайте Актера, HelloActor.java
В методе on onReceive
вы можете обрабатывать данные, отправлять электронные письма и т.д.
public class HelloActor extends UntypedActor {
@Override
public void onReceive(Object message) throws Exception {
// Do the processing here. Or better call another class that does the processing.
// This method will be called when ever the job runs.
if (message.equals("tick")) {
//Do something
// controllers.Application.sendEmails();
} else {
unhandled(message);
}
}
}
Надеюсь, что это поможет.