On Aug 22, 1:51*pm, Sean DiZazzo <(E-Mail Removed)> wrote:

> On Aug 22, 1:30*pm, Karthik Gurusamy <(E-Mail Removed)> 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