I recently got some feedback from a Java EE 5 Tutorial user who saw some odd behavior when using a modified version of the EJB Timer Service example. The user's modified app attempts to create a repeating 3 second timer like this:
public void setTimer(long intervalDuration) {
Timer timer = timerService.createTimer(0, intervalDuration, "Created new timer");
}
And on the client:
long intervalDuration = 3000; timer.setTimer(intervalDuration);
The user added a call to check the system time to measure the accuracy of the timeout in the @Timeout method in TimerSessionBean:
@Timeout
public void timeout(Timer timer) {
logger.info(System.currentTimeMillis() + "Timeout occurred");
}
The user was surprised to see the interval timing as 7 seconds, not 3 seconds. I was surprised as well. I posed the question to the ejb@glassfish.dev.java.net mailing list, and heard back from Ken Saks, the EJB.next spec lead and the lead engineer for EJB 3 here at Sun:
The EJB Timer Service is not targeted towards very fine-grained timeouts, so there's a default minimum imeout interval of 7000 ms defined within Glassfish. That property can be changed via theminimum-delivery-interval-in-millisattribute indomain.xml.
Note that this is GlassFish-specific behavior. The EJB 3 spec doesn't define minimum timeout values, although it does say that the Timer Service is not designed for extremely precise operations required by real-time applications, as Ken pointed out in his response.
Update: I corrected Ken's email above to fix his typo of 7 ms to 7000 ms (that is, 7 seconds). domain.xml's DTD specifies a default value of 7000 ms for minimum-delivery-interval-in-millis.
Update 2: Update 4 of the Java EE 5 Tutorial contains an updated example with an 8 second/8000 ms timer, and a note on GlassFish's minimum default timeout value.
