currentMillis() and new Date() must not accurate as the timer must not start at the exact timepoint according to the spec.
And AFAIK there is no possibility to get the current schedule, only if you store it by yourself
To store it by myself would mean to interpret the ScheduledExpression ? (This is non trivial :-( )
Maybe calculating getNextTimeout() - getTimeRemaining() would do the trick ?
Yeah, that is an option. The other one is to store the nextTimeout somewhere and reference it in the next invocation.
But still there is a very small frame where you can go wrong, i.e. a GC between method call (from the container) and the execution of the calculation
But I think another difficulty is that you are not sure whether the invocation is after the server was down (ok, can only happen if persistent=true)
Michael Illgner wrote:
OK, I can use System.currentMillis() oder new Date(), but is this always accurate ? Is there a guaranteed maximum delay between a configured and the actual execution ?
Depends on why you need that time or what actually does that time represent? Are you after the time at which the timeout method was executed? If yes, then using System.currentTimeIn....() API is the right way. If you explain your use case a bit more, we might be able to provide some more inputs.
Let me explain the use case.
We have a cluster of application servers distributed between two datacenter in different locations, these AS use an oracle database, which is high available by its on means, this database uses a reserved network connection for its sychronization between the nodes. Therefore its is possible (and we alread have seen) that the connection between the datacenter is lost, we have a cluster split between the JBoss AS, but the database itself is available from both datacenter and in sync since the network connection between the database nodes is not lost.
We implemented an HA Timer based on Wolfs examples from the JBoss quickstarts ;-) http://www.jboss.org/jdf/quickstarts/jboss-as-quickstart/cluster-ha-singleton/ and we have to ensure that even in the case of a cluster split where two timers may exists a timer event is only send once. So my idea was to use the scheduled time as a kind of id "the event that was supposed to sent at 15:10:00" and to implement a safety net that every event gets written in s semaphore table in the database. These events are rare, may be a handfull per hour, so a resolution of second (or even a minute) is fine enough. I will try to calculate the scheduled timestamp from the timeRemaining and nextTimeout attributes and round the result to full seconds.
Yeah, I taked with Heiko about that problem a bit during the 'Expertenkreis Java', Cluster splitt is a problem if you need to be sure that a timer event must be unique.
If the schedule is not very often I suppose the identification with a sec or minute will be enough.
That will only be simple if the timer is not persistent, in that case the timer might be started couple of times after restart the server .
What if you use the difference between two events also.
Lets say every 5 minutes.
You have a cluster splitt.
First start at 00:00 and finish
Other split note at 00:00:35 anyway what reason
So if you calculate 00:00:35 +- (5min/2) the event must be the same. Maybe you use a smaller window.
But I think this will be a save version, right?