On Aug 22, 1:51 pm, Sean DiZazzo <[EMAIL PROTECTED]> wrote: > On Aug 22, 1:30 pm, Karthik Gurusamy <[EMAIL PROTECTED]> wrote: > > > > > Hi, > > > I'm working on acronlike functionality for my application. > > The outer loops runs continuously waking every x seconds (say x=180, > > 300, ..). > > It needs to know what events incronhas expired and for each event do > > the work needed. > > > It's basically like unixcronor like a calendar application with some > > restrictions. The outer loop may come back a lot later and many events > > might have missed their schedule -- but this is okay.. We don't have > > to worry about missed events (if there were n misses, we just need to > > execute call back once). > > > Let's take some examples [Let e denotes an event] > > e1: hour=1 min=30 # Run every day once at > > 1:30 AM > > e2: wday=0, hour=1 min=0 # run every Monday at 1 AM > > e3: month=10, day=10, hour=10 min=0 # run on October 10th, 10 AM > > every year > > > class Cron_Event (object): > > def __init__ (year=None, month=None, day=None, hour=None ..etc) > > # do init > > > classCron(object): > > def __init__ (): > > # do init > > def event_add (e): > > # add an event > > def execute() > > # see if any events has "expired" .. call it's callback > > # I'm looking for ideas on how to manage the events here > > > From outer loop > >cron=Cron() > > # create various events like > > e1 = Cron_Event(hour=1) > >cron.event_add(e1) > > e2 = Cron_Event(wday=0, hour=1) > >cron.event_add(e2) > > > while True: > > sleep x seconds (or wait until woken up) > > cron.execute() > > # do other work.. x may change here > > > If I can restrict to hour and minute, it seems manageable as the > > interval between two occurrences is a constant. But allowing days like > > every Monday or 1st of every month makes things complicated. Moreover > > I would like each constraint in e to take on multiple possibilities > > (like every day at 1AM, 2 AM and 4 AM do this). > > > I'm looking for solutions that can leverage datetime.datetime > > routines. > > My current ideas include for each e, track the next time it will fire > > (in seconds since epoch as given by time.time()). Once current time > > has passed that time, we execute the event. e.g.>>> datetime.datetime.now() > > > datetime.datetime(2008, 8, 22, 13, 19, 54, 5567)>>> time.time() > > > 1219436401.741966 <--- compute event's next firing in a format like > > this > > > The problem seems to be how to compute that future point in time (in > > seconds since epoch) for a generic Cron_Event. > > > Say how do I know the exact time in future that will satisfy a > > constraint like: > > month=11, wday=1, hour=3, min=30 # At 3:30 AM on a Tuesday in > > November > > > Thanks for your thoughts. > > > Karthik > > I only scanned your message, but maybe datetime.timedelta() will > help.. > > >>> import datetime > >>> now = datetime.datetime.now() > >>> print now > > 2008-08-22 13:48:49.335225>>> day = datetime.timedelta(1) > >>> print day > 1 day, 0:00:00 > >>> print now + day > > 2008-08-23 13:48:49.335225
Thanks, I found using a more efficient algorithm tricky and seemed error prone. [I do welcome ideas still if anyone has a cool solution] I used your idea and took the easy way out by using a brute-force search. Here is an outline if anyone faces similar problem: hours, minutes are lists: say for every day at 1:30 pm and 2:45 pm, hours=[13, 14] and minutes=[30, 45,]. I restricted myself to minutes and hours (and every day) to simplify the problem. def set_expiry_time_check_in_a_day (self, now, target, hours, mins, flags=set()): """ A small utility routine to simulate 'goto' Looks like now could be computed inside this function -- the small drift due to time taken in this function should be negligible """ # let's see if in today we can find an expiry # we do brute force search starting with the smallest hour for hour in hours: for min in mins: target = target.replace(hour=hour, minute=min, second=0, microsecond=0) if 'is_debug_1' in flags: print "Trying target time: %s..." % target if target > now: if 'is_debug_1' in flags: print "Found target time: %s" % (target, ) return target # simulates a break from two loops return None def set_expiry_time (self, event, flags=set()): """ For a given event, compute and remember when it will fire next """ now = datetime.datetime.now() target = now # start checking from now.. # assumption, hours and mins are atleast one int element array # and they are in sorted order hours = event.spec['hours'] mins = event.spec['minutes'] tries = 0 while True: # runs of each day.. tomorrow ... tries += 1 if tries > 50: # safety valve, we are basically in infinite loop raise Exception("Tried 50 times.. in infinite loop??") target_found = self.set_expiry_time_check_in_a_day(now, target, hours, mins, flags) if target_found is not None: # found a match on "this" day target = target_found break # we need to increase the day count.. increment = datetime.timedelta(days=1) target += increment # added 24 hours .. let's go and check tomorrow ... event.target = target > > ~Sean -- http://mail.python.org/mailman/listinfo/python-list