package services; import akka.actor.ActorSystem; import akka.actor.Cancellable; import managers.MediaManager; import models.services.EmailService; import org.joda.time.DateTime; import org.joda.time.Seconds; import play.api.inject.ApplicationLifecycle; import play.libs.F; import scala.concurrent.duration.Duration; import javax.inject.Inject; import javax.inject.Singleton; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; /** * Created by Iven on 08.12.2015. */ @Singleton public class ScheduleService { private EmailService emailService; private MediaManager mediaManager; private ActorSystem system; private ApplicationLifecycle lifecycle; @Inject public ScheduleService(EmailService emailService, MediaManager mediaManager, ApplicationLifecycle lifecycle) { system = ActorSystem.create(); this.emailService = emailService; this.mediaManager = mediaManager; this.lifecycle = lifecycle; schedule(); } private void schedule() { // set the email schedule to next full hour clock for sending daily and hourly emails Cancellable emailScheudler = system.scheduler().schedule( Duration.create(nextExecutionInSeconds(getNextHour(), 0), TimeUnit.SECONDS), Duration.create(1, TimeUnit.HOURS), () -> { emailService.sendDailyHourlyNotificationsEmails(); }, system.dispatcher() ); // cancel it on application stop lifecycle.addStopHook(() -> { emailScheudler.cancel(); return CompletableFuture.completedFuture(null); }); // Sets the schedule for cleaning the media temp directory Cancellable cleanUpScheudler = system.scheduler().schedule( Duration.create(0, TimeUnit.MILLISECONDS), Duration.create(2, TimeUnit.HOURS), () -> { mediaManager.cleanUpTemp(); }, system.dispatcher() ); // cancel it on application stop lifecycle.addStopHook(() -> { cleanUpScheudler.cancel(); return CompletableFuture.completedFuture(null); }); } /** * Returns the next full hour of the current time * * @return Next hour of current time */ private int getNextHour() { return (new DateTime()).plusHours(1).getHourOfDay(); } /** * Calculates seconds between now and a time for hour and minute. * * @param hour Hour * @param minute Minute * @return Seconds */ private int nextExecutionInSeconds(int hour, int minute) { return Seconds.secondsBetween( new DateTime(), nextExecution(hour, minute) ).getSeconds(); } /** * Returns a DateTime for hour and minute. * * @param hour Hour * @param minute Minute * @return DateTime */ private DateTime nextExecution(int hour, int minute) { DateTime next = new DateTime() .withHourOfDay(hour) .withMinuteOfHour(minute) .withSecondOfMinute(0) .withMillisOfSecond(0); return (next.isBeforeNow()) ? next.plusHours(24) : next; } }