Saturday, December 29, 2012

Distant Scheduled Events Unreliable in Twisted

Someone recently asked a question about whether reactor.callLater could be used to precisely schedule events in the very distant future. The person gave an example of scheduling now - December, 2012 - an event to run at a particular time in December 2014 - a date two years in the future.

One thing to keep in mind about scheduled events (actually, any events) in a Twisted-using application is that the whole system is cooperative and single-threaded. So an event scheduled to run at a specific time - Twisted uses Python floats to represent a time (seconds since the epoch) at which to run scheduled events - cannot run at that time if something else happens to be running when that time comes around. For example, if you have a prime calculator and you're busy calculating a 10,000 digit prime number on December 30, 2014 at 15:30:00 then your event scheduled for that time is not going to run. Instead, it'll run sometime after the prime calculation is finished.

The asker knew this, though, and was only curious about whether there were any intrinsic scheduling limitations related to very distant times. The answer is that there is a limitation, and I've already alluded to it in the paragraph above.

Twisted uses Python floats to represent time. The precision available to floating points declines as the values themselves get larger (this is why they're called "floating points"! The decimal point can move around).

At 2 ** 51, values that differ by less than 0.5 cannot be represented. At 2 ** 52, the range grows to 1.0, and above 2 ** 53, the representation only supports even integers (you can probably see a pattern here - add a bit to the magnitude, subtract a bit from the precision). As Twisted is treating this value as a number of seconds since an arbitrary starting point, this means that 2 ** 53 seconds after that starting point, scheduling granularity has dropped to 2 seconds; ie, there is only one point in time out of every two second interval at which an event can be scheduled. Try to schedule it for a different time and it will silently be adjusted to the time in that interval which can be represented. As a specific example, if you tried to schedule an event to run at 9007199254740993 seconds after the epoch, it would most likely run at 9007199254740992 seconds after the epoch instead.

What does this mean in practical terms? Perhaps not a lot. Assuming our current system of marking the passage of time continues in use until then, 9007199254740992 seconds after the epoch falls about 25 minutes before midnight on November 11th (a Sunday), in the year 285,428,751.


  1. 9007199254740992 is quite some uptime. Better not use EC2 for that application!

  2. Excellent point! Clearly we need to redirect some of the Twisted development effort to constructing a platform which can provide uptimes of multiple hundreds of millions of years, then we can revisit this issue.