Ben Cracknell
Ben Cracknell

Reputation: 271

Check if a time with matching units has past since the last check

I have a system that needs to trigger at certain intervals

If it is given the following:

minutes:25, seconds:10

It should then trigger every hour, 25 minutes and 10 seconds past the hour. For example, 7:25:10, 8:25:10, 9:25:10, and so on.

This would be simple enough, and I already have that code working. The problem is that it only works if the system checks at least once a second, otherwise it will miss a trigger.

So how can I check if the trigger units would have matched the current time units since the last check? The time between checks will vary greatly.

The trigger units are stored like this:

// units that must match the current time <Calendar Unit, Trigger>
private Map<Integer, Integer> triggerUnits;

Upvotes: 0

Views: 113

Answers (3)

AlexR
AlexR

Reputation: 115378

First move to enum instead of map. The enum can contain hour, second, day, whatever. The good new is that such enum already exists in JDK and is called TimeUnit. Each member of this enum knows to translate the time to other units.

So, parse string hour:5. Translate the 5 hours to 3600*5*1000 milliseconds. This value will be used in your system. You have several possibilities but I'd suggest you to start from java.util.Timer. Each task can be scheduled in the timer. It uses one single thread for execution of all tasks.

If you want you can use use Executors framework:

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.schedule(...);

The schedule method here directly works with time units. You even do not have to translate from one unit to another.

Upvotes: 2

Femi
Femi

Reputation: 64700

Not precisely an answer for what you've asked, but I'd suggest using cron4j: the Predictor sounds like it is almost exactly what you need. Translate your spec into cron format, and then pass it to the Predictor and it will actually tell you the absolute time of the next execution. You can just schedule your check to happen at that moment in time or use a ScheduledExecutor to fire the job.

Might be a bit more complicated in some ways (and its an additional dependency), but completely eliminates the timing risk.

Upvotes: 1

nitegazer2003
nitegazer2003

Reputation: 1193

Each time you trigger the system, store the next time that the code needs to be triggered. During the checks, simply check if the current time has passed this "next time", and if so, then trigger the system.

Upvotes: 1

Related Questions