views:

196

answers:

2

Hi, I am forced to execute a periodic task using a timer that is invoked at a different interval as the period I'd like to execute this task.

Note that the timeout does not occur 100% accurately; i.e. timeout(javax.ejb.Timer timer) in the code below might be invoked at intervals 100, 98, 105ms etc.

So, I came up with this, which is sort of okay. But occasionally the task will be executed twice before the intended interval passes, or the interval becomes a little longer than I intend.

Do you have any better idea than this? (Code is simplified pseudo-code, will be used within a EJB container)

import javax.annotation.Resource;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

public class TimerBean {
    private static final long TASK_INTERVAL = 1530;
    private static final long TIMEOUT = 100;

    @Resource
    private TimerService timerService;


    public void startTimer() {
        timerService.createTimer(100, TIMEOUT, null);
    }

    @Timeout
    public void timeout(javax.ejb.Timer timer) {
        if(isApproxTime(timer, TASK_INTERVAL)){
            //do stuff
        }
    }

    private boolean isApproxTime(Timer timer, long targetInterval) {
        long modulus = timer.getNextTimeout().getTime() % targetInterval;
        return modulus < TIMEOUT;
    }
}

EDIT: I'd like to avoid state other than ejb.Timer, so saving the time of last invocation is not an option.

+1  A: 

These are odd requirements indeed. But what the heck.

Can you create timers whenever you want? If so, adjust the task interval to be the amount of time remaining before your target interval elapses, or some smaller amount. This will drift, but the duration between events will be roughly equal to your target.

I don't have a solid feeling from your code about how much control you have over things. For example, is there a window of TIMEOUT that you are allowed to specify? Or is a single value dictated to you, and you have no control over it whatsoever?

If it's the later (no control at all over it), then what you've put together is pretty much all you can do. I personally would push back HARD on the requirement of not storing state in this bean. The state in question is not at all persistent or anything else that would make this a problem.

Kevin Day
Thanks for your answer. We had other issues arising from this requirement, and we finally got rid of this requirement. Now I'm simply using the right interval!
Enno Shioji
A: 

Quartz should give you more accurate and more controllable timers

medopal