Sunday, November 1, 2009

Timers During Daylight Savings Time

With Daylight Savings Time just passing early this morning, it occurred me that timers could have a subtle bug. This occurred to me today because I was running some overnight tests last night. While the tests exhibited no issues with the extra hour, I can foresee scenarios where it could have.

For instance, let's say you have a C++ class that looks something like this (Pseudo-code):


class Timer : public Thread
{
public:
virtual void run()
{
while (running)
{
get current time
while (current time < time value at top of timer queue)
{
pop
notify timer listener
}
wait for top of timer queue to expire
}
}
};


This code is relatively flawless, except, what if the current time drops back an hour? This can occur, depending on how you retrieve your time. Now, in the worst case, all of the timers in your system won't trigger for an extra hour. This basically means your code is mostly nonfunctional for an hour after Daylight Savings Time occurs. In an application, you can just restart the application and the problem vanishes. On server code, this can be a bigger issue at this peculiar time.

Here's one solution I thought of to correct this potential problem:

class Timer : public Thread
{
public:
virtual void run()
{
while (running)
{
get current time
if (current time < last known time)
{
create temporary queue
pop each element of queue, subtract difference, push to new queue
pop each element off temporary queue, push back to original queue
}

while (current time < time value at top of timer queue)
{
pop
notify timer listener
}
set last known time equal to current time
wait for top of timer queue to expire
}
}
};


If you do this, you basically have this level of correction code to handle this peculiar scenario. The solution is that every timer is adjusted to handle the problem. Of course, this isn't a perfect solution, but it's one way I can think to mitigate the issue. I may write a test later to see if this solution is good enough or if there are better ones. I suspect many well-known timer libraries handle this already, but in C++, you can sometimes justify rolling your own depending on your needs.

No comments: