From 33d1c4b817dab9c5f36e35fc97a6b69c37b3436a Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 8 Jun 2006 04:09:24 +0000 Subject: Implement leap-second caching. Not tested as root yet. --- leapsecond.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'leapsecond.py') diff --git a/leapsecond.py b/leapsecond.py index 565ad5bb..3148687e 100755 --- a/leapsecond.py +++ b/leapsecond.py @@ -4,7 +4,7 @@ # GPS time, which changes occasionally due to variations in the Earth's # rotation. # -import urllib, re, random +import os, urllib, re, random, time, calendar, stat __locations = [ ( @@ -23,6 +23,11 @@ __locations = [ ), ] +# File contasining cached offset data. +# Two fields: the offset, and the start of the current six-month span +# between times it might change, in seconds since Unix epoch GMT. +__cachepath = "/var/run/leapsecond" + def retrieve(): "Retrieve current leap-second from Web sources." random.shuffle(__locations) # To spread the load @@ -37,7 +42,50 @@ def retrieve(): except: pass else: - raise ValueError + return None + +def last_insertion_time(): + "Give last potential insertion time for a leap second." + # We need the Unix times for midnights Jan 1 and Jul 1 this year. + when = time.gmtime() + when.tm_mday = 1 + when.tm_hour = when.tm_min = when.tm_sec = 0 + when.tm_mon = 1; jan = int(calendar.timegm(when)) + when.tm_mon = 7; jul = int(calendar.timegm(when)) + # We have the UTC times of the potential insertion points this year. + now = time() + if now > jul: + return jul + else: + return jan + +def get(): + "Fetch GPS offset, from local cache file if possible." + stale = False + last_insertion = last_insertion_time() + if not os.path.exists(__cachepath): + stale = True + else: + cfp = open(__cachepath) + txt = cfp.read() + cfp.close() + (offset, valid_from) = map(int, txt.split()) + if valid_from < last_insertion: + stale = True + # We now know whether the cached data is stale + if not stale: + return offset + else: + current_offset = retrieve() + # Try to cache this for later + if current_offset != None: + try: + cfp = open(__cachepath, "w") + cfp.write("%d %d\n" % (offset, last_insertion)) + cfp.close() + except (IOError, OSError): + pass + return current_offset if __name__ == '__main__': - print "GPS offset is: %d" % retrieve() + print retrieve() -- cgit v1.2.1