Trying lovely.remotetask for cron jobs

Tags: grok

I tried out lovely.remotetask for cron jobs in a sample grok site. It was high time for me to get dirty with utilities in a grok site.

First things first: put lovely.remotetask in the install_requires section of your setup.py.

Secondly, you need a “task service”: something that actually runs the tasks you give it to run. I registered it as a local utility in my grok site:

class CronService(lovely.remotetask.TaskService):
    pass


class Mysite(grok.Site):
    interface.implements(IMysite)
    grok.local_utility(
        CronService,
        provides=lovely.remotetask.interfacesITaskService,
        name='cronservice')

Thirdly, you need the actual task. This just has to be a callable. For now I restricted myself to a simple “print” instead of immediately doing a zodb pack. Wrap it in a lovely.remotetask.task.SimpleTask and register it as a global utility with some name:

def echo():
    print "something"

grok.global_utility(SimpleTask(echo), name='echo', direct=True)

The last thing is to add the task from step 3 to the task service from step 2. There’s no out-of-the-box way to do that right away with utility registration or through configuration. You could react to the site’s object-created event, I guess.

I recently experimented with a new buildout recipe that creates a site in an empty Data.fs and optionally calls a method after that by feeding a generated python file to zopectl run. So I set up a method that I could call from there:

def setup_cron_job(site):
    every_minute = tuple(range(60))
    service = site.getSiteManager().queryUtility(ITaskService, 'cronservice')
    if not service:
        raise RuntimeError("No cronservice utility found")
    tasks = [job.task for job in service.jobs.values()]
    if u'echo' not in tasks:
        service.addCronJob(u'echo', minute=every_minute)

I got rewarded by a “something” being printed every minute. I’m not sure I’m happy with it yet. A regular cron job that calls a view is straightforward. But there’s no password in plain text anywhere (which you need with a cron job) on your filesystem and that is again a huge bonus. You even do without an admin user… I’ll have to see how it plays out in more elaborate situations.

Comments? Better examples? An actual simple cron example with zc.async? Please mail them to reinout@vanrees.org :-)

Comment by Radim Novotny:

I’m using lovely.remotetask with Plone to query third party server for organization data. It is not cron-like service, but asynchronous query service.

User enters ID of the organization, and as soon as blurs from the input field, remote task service is started. While user is entering additional details (email address) the service queries remote server for organization name and address. As soon as data from the remote server are ready, they are displayed on the page and entered to hidden fields of the input form. Remote query take about 1-2 seconds.

 
vanrees.org logo

About me

My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):