Thursday, March 31, 2005

A task-scheduling module

Part of the next release of Spyce will be the new scheduler module. This actually has no Spyce dependencies, so it may be useful in any (web or non-web) application that needs to run tasks at given times or intervals. Some things I have used it for:
  • Scan the log for errors and email me a summary
  • vacuum (pre-autovacuum daemon days...)
  • Purge stuff from the global cache
  • Send email to users whose accounts are about to be suspended
Why a python module instead of cron? The primary benefit in my mind is that scheduler runs as a thread of your application (or app server, in Spyce's case), so you can access your database connection pool, cache, or other global state without jumping through nasty hoops. This is a bigger deal the more complex your application is... Putting logic here also makes deploying to testing or release servers (or to a client) a matter of running "svn up" rather than having to mess with crontab.

You can browse the svn source here: http://svn-hosting.com/svn/spyce/trunk/spyce/scheduler.py

>>> import scheduler
>>> help(scheduler)
Help on module scheduler:

DESCRIPTION
    A module for scheduling arbitrary callables to run at given times
    or intervals, modeled on the naviserver API.  Scheduler runs in
    its own thread; callables run in this same thread, so if you have
    an unusually long callable to run you may wish to give it its own
    thread, for instance,
    
    schedule(lambda: threading.Thread(target=longcallable).start())
    
    Public functions are threadsafe.

CLASSES
    Task
    
    class Task
     |  Instantiated by the schedule methods.
     |  
     |  Instance variables:
     |    nextrun: epoch seconds at which to run next
     |    interval: seconds before repeating
     |    callable: function to invoke
     |    last: if True, will be unscheduled after nextrun
     |  
     |  (Note that by manually setting last on a Task instance, you
     |  can cause it to run an arbitrary number of times.)
     |  
     |  Methods defined here:
     |  
     |  __init__(self, firstrun, interval, callable, once)

FUNCTIONS
    pause()
        Temporarily suspend running scheduled tasks
    
    schedule(interval, callable, once=False)
        Schedules callable to be run every interval seconds.
        Returns the scheduled Task object.
    
    schedule_daily(hours, minutes, callable, once=False)
        Schedules callable to be run at hours:minutes every day.
        (Hours is a 24-hour format.)
        Returns the scheduled Task object.
    
    unpause()
        Resume running scheduled tasks.  If a task came due while
        it was paused, it will run immediately after unpausing.
    
    unschedule(task)
        Removes the given task from the scheduling queue.

2 comments:

Anonymous said...

I recommend using VisualCron instead of the task scheduler.

regards,

Ryan

Tim Lesher said...

<sarcasm>
Great idea, Ryan. That will work great when running a Spyce app on my colocated FreeBSD box.
</sarcasm>