Reputation: 687
I have a Play 2.3 project where I need to schedule an action once every whole hour, so I use Akka to schedule it in the Global.onStart. The action definitely takes far less than 1 hour to complete (it checks a database for potential updates, then executes a handful of web requests based on them).
However, every time the action runs except the first, it is delayed by 1 second. So after 60 hours/updates, it's delayed by a whole minute, and presumably after about 9 months it will be delayed by a whole hour.
At first I tried setting the frequency to (60 * 60) - 1 seconds, and it worked at first, but sometimes it's offset anyway and eventually it ends up running too late.
It seems that the frequency doesn't start counting down (so to speak) until the action is complete, which results in this delay, so what can I do do prevent this drift?
Here's the code I have to calculate delays and to schedule the action:
// Time until next full hour
static public FiniteDuration getDelay()
{
Calendar currentCalendar = Calendar.getInstance();
long minute = currentCalendar.get(Calendar.MINUTE);
long second = currentCalendar.get(Calendar.SECOND);
long ms = currentCalendar.get(Calendar.MILLISECOND);
minute = (60L - minute) * 60 * 1000;
second = (60 - second) * 1000;
ms = 1000L - ms;
long delay = minute + second + ms;
return FiniteDuration.create(delay, TimeUnit.MILLISECONDS);
}
// Update once every 60 minutes
static public FiniteDuration getFrequency()
{
return FiniteDuration.create(60, TimeUnit.MINUTES);
}
Akka.system().scheduler()
.schedule(getDelay(), getFrequency(),
Publisher.makeRunnable(), Akka.system().dispatcher());
Upvotes: 2
Views: 514
Reputation: 2786
It seems your delay calculation to the nearest whole hour did not take into account the carry-over:
say, current time is 3:58:49.999
, the diff to 4:00:00.000
is
00:01:10.001. However, running your code would be 00:02:11.001
.
Upvotes: 0
Reputation: 2785
The akka scheduler does not purport to be accurate in its scheduling as it simply maintains a queue of jobs which it checks on each "tick" (see the warning on this page ). If you want to have accurate timing of your jobs, I suggest you use a cron-like library such as Quartz so that you can issue messages at the right time. This allows you to more precisely schedule jobs according to wall clock time than rely on Akka's notion of a "tick".
Upvotes: 1