Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Seeking ideas for a cron implementation

Reply
Thread Tools

Seeking ideas for a cron implementation

 
 
Karthik Gurusamy
Guest
Posts: n/a
 
      08-22-2008
Hi,

I'm working on a cron like functionality for my application.
The outer loops runs continuously waking every x seconds (say x=180,
300, ..).
It needs to know what events in cron has expired and for each event do
the work needed.

It's basically like unix cron or 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

class Cron (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
 
Reply With Quote
 
 
 
 
Sean DiZazzo
Guest
Posts: n/a
 
      08-22-2008
On Aug 22, 1:30*pm, Karthik Gurusamy <(E-Mail Removed)> wrote:
> Hi,
>
> I'm working on a cron like functionality for my application.
> The outer loops runs continuously waking every x seconds (say x=180,
> 300, ..).
> It needs to know what events in cron has expired and for each event do
> the work needed.
>
> It's basically like unix cron or 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
>
> class Cron (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

~Sean
 
Reply With Quote
 
 
 
 
Karthik Gurusamy
Guest
Posts: n/a
 
      09-07-2008
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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Tree implementation, ideas for keyboard input method needed Bubba C Programming 24 01-18-2012 09:21 PM
Knowing the implementation, are all undefined behaviours become implementation-defined behaviours? Michael Tsang C++ 32 03-01-2010 09:15 PM
Best method for seeking to n lines before end of file [ implementation of tail ] graemenewlands@gmail.com Perl Misc 6 06-01-2006 03:44 PM
Seeking ideas for spare HDDs Evil Bastard NZ Computing 5 09-05-2004 03:49 AM
Implementation ideas? Flexible string matching Kirk Haines Ruby 8 08-13-2004 03:18 PM



Advertisments