wiki:TracCronPlugin

Trac Cron Plugin

Description

This plugin adds a scheduler inside the Trac process that can handle any sort of task written in the python language. Main features are:

  • Task are plugin
  • Bundled out-of-the-box task
  • Scheduler are plugin
  • Bundled out-of-the-box scheduler new cron syntax is supported
  • Listener mechanism to be notified of task execution
  • Bundled out-of-the-box listener new admin panel for listener
  • Task execution history new rss feed is available

The plugin provides an administration panel to help scheduling.

Administration panel of Trac Cron Plugin

Bugs/Feature Requests

Existing bugs and feature requests for TracCronPlugin are here.

If you have any issues, create a new ticket.

Download

Lastest release

Current stable release is 0.3.1 You can use easy_install or pip to download the latest package into your python environment

$ easy_install TracCronPlugin
or 
$ pip install TracCronPlugin

or download distributions files at pypi (only source distributions)

Source

You can clone TracCronPlugin from here using Mercurial, or browse the source. Originally, TracCronPlugin source is hosted in trac-hacks.org svn. I won't maintain any longer.

Example

My company needed to synchronize trac users with an external account source. The job was done by an ETL but fine tuning of trac user was still done by a our modified version of Trac by clicking on a button on the admin panel that call a well designed API. So instead of manually clicking on the button I searched for a way to automate it. Unfortunately, I did not find any plugin for this and even if I could use a unix cron task or an windows AT command to plane the task, I thought it would be better done inside Trac process.

So if you have any function for entry point of a process (I mean trac related process) and you want to plane it as a job, Trac Cron Plugin is for you.

Simply create in a module (.py) a class that implements the ICronTask and put it inside the plugins directory. Then you can either trick the trac.ini either comfortably use the dedicated admin panel.

How to write a task

You have to write python class that inherits of ICronTask which code is below:

class ICronTask(Interface):
    """
    Interface for component task
    """
    
    def wake_up(self, *args):
        """
        Call by the scheduler when the task need to be executed
        """
        raise NotImplementedError
    
    def getId(self):
        """
        Return the key to use in trac.ini to configure this task
        """
        raise NotImplementedError
    
    def getDescription(self):
        """
        Return the description of this task to be used in the admin panel.
        """
        raise NotImplementedError

Let's take a look at the heartbeat task packed with TracCronPlugin:

class HeartBeatTask(Component,ICronTask):
    """
    This is a simple task for testing purpose.
    It only write a trace in log a debug level
    """
    
    implements(ICronTask)
    
    def wake_up(self, *args):
        if len(args) > 0:
            for arg in args:
                self.env.log.debug("Heart beat: " + arg)
        else:
            self.env.log.debug("Heart beat: boom boom !!!")
    
    def getId(self):
        return "heart_beat"
    
    def getDescription(self):
        return self.__doc__

You need to implement the interface and to put the definition of the task inside the wake_up method

How to install the task

Since tasks are components you just have to put the class definition of your task in a python module in the plugins directory. You can either create a .py file and put it in plugins directory or package the .py file into an eggs you'll leave in plugins directory.

TracCronPlugin will show up the task in it administration panel. Enjoy !

Configuration

The plugin can be entirely configured from either trac.ini or the administration panel. The section name of TracCronPlugin is traccron, here is a full sample

[traccron]
ticker_enabled = True
ticker_interval = 1
heart_beat.daily = 21h19, 21h20
heart_beat.daily.enabled = True
hear_beat_daily.arg = Good Morging
heart_beat.enabled = True
heart_beat.hourly = 17, 18
heart_beat.hourly.enabled = False
heart_beat.monthly = 15@21h15, 15@21h16
heart_beat.monthly.enabled = False
heart_beat.weekly = 4@21h28, 4@21h29
heart_beat.weekly.enabled = False

Global setting

ticker_enabled = True

This control the object called ticker which is the thread that launch tasks. If False, no ticket (no thread) is created so your Trac is merely like no cron is installed. This is the more global setting you can act on to enable or disable ALL task. Default value is True.

ticker_interval = 1

This key control the interval between each wake up of the ticker. The ticker thread periodically wake up to see if there is task to execute. Then the ticker thread go sleep for the amount of minutes specified by this key. You should not have modify this value except if you have system load issue. Default value is 1.

Task setting

For each task loaded by Trac Component manager, Trac Cron Plugin have those parameters. Let's look at hear beat task:

Enable/Disable a task

heart_beat.enabled = True

This is the second way to enable or disable a task. Since ticker_enabled is global and so all task will be affected, this key only affect one task. If False, whatever schedule the task have, no one will be triggered, so this is a way to disable a task while keep all the schedule in place for the time you will enable the task. Default is True.

Task scheduling

heart_beat.daily = 21h19, 21h20

This control the daily scheduler. As this name suggest, it trigger the task every day. You need to provide time you want the task to execute. You can give a comma separated list to trigger the task at multiple time everyday. Default is no value.

heart_beat.hourly = 17, 18

The goal of this scheduler is to trigger task every hours. You provide minute when you want the task to be executed. Accept comma separated list of values. Default is no value.

heart_beat.monthly = 15@21h15, 15@21h16

This scheduler trigger task that need to be executed once a month. You provide the day in month and the hour when the task will be launched. The day is the index of the day starting at 1. Accept comma separated value. Default is no value

heart_beat.weekly = 4@21h28, 4@21h29

This sceduler trigger task that need to be executed once a week. You provide the day in week and the hour when the task will be launched. The day is the index of the day starting at 0 (Monday is 0). Accept comma separated value. Default is no value

Enable/Disable a schedule

Each schedule can individually be enabled or disabled. This the configuration for daily scheduler:

heart_beat.daily.enabled = True

This enables or disables the trigger. If False, the scheduler will not trigger the task. Default is True.

Pass argument to a task

You can pass arguments to the task on a per schedule basis. Here an example for daily schedule:

hear_beat_daily.arg = Good Morging

When the daily schedule triggers the task, the value of the key is passed to the wake_up call. Parameters can be coma separated multiple value. Default is empty

Bundled Task

Besides the HearBeat task provided for testing purpose, TracCronPlugin comes with the following useful task.

sleeping_ticket

This task reminds reporter about orphaned ticket and assigned user about sleeping ticket. An orphaned ticket is a ticket in new status since more than a given amount of day. An email notification is sent to the reporter in such a case. A sleeping ticket is a ticket assigned to an user, but the user either did not accept it or did not touch the ticket(make comment for example) since more than a given amount of day. The assigned user is notified in such a case. The delay is an optional parameter associated with each schedule. Default value is 3 day.

unreachable milestone

Note: Since 0.2dev_r9388

This task scan still opened tickets in near milestone. Such a situation means that those tickets will probably not be part of the milestone. The task send a mail to user defined with unreachable_milestone.recipient (default is empty) for each milestone with the list of still opened tickets. You may want to set the value to the release manager user. Reporter and owner are notified too but only for their tickets. The task looks for near milestone until 3 days ahead. You can change the value with parameter either by setting unreachable_milestone.<schedule>.arg or in admin panel.

This is an example of the mail for release manager:

Hello,

The milestone milestone1 is near to be closed. Its due date is 11-30-2010.

Unfortunately we have detected some still opened ticket.
Please consider to postpone them or ensure they will meet the milestone due date.

These ticket are

testing ticket
http://localhost:8000/dummy/ticket/1

testing ticket
http://localhost:8000/dummy/ticket/3



Best regards.

--
My Project <http://localhost:8000/dummy>
My example project

Auto postpone task

note: since 0.2dev_r9390

Trac allow the administrator to postpone still opened ticket in a given milestone when he close a this milestone. But this is not mandatory. The auto postpone task will help to not forget opened tickets in closed milestone. The task look for such tickets and postpone them in the more recent still opened milestone (milestone must have a due date)

Ticket deadline task

note: since 0.3

This task notify to ticket's reporter and owner when its ticket is near the deadline as a custom field. You can add date field for ticket using DateFieldPlugin. Besides scheduler settings, there are 3 options to configure when DateFieldPlugin is used.

  • days_before: notify days before the deadline
  • date_field: ticket custom field's name
  • date_format: this format string is handled by datetime module

Ticket with due date

Here is a sample configuration for trac.ini.

[traccron]
ticker_enabled = True
ticker_interval = 1
ticket_deadline.cron = * 0 10 * * ? * 
ticket_deadline.cron.enabled = True
ticket_deadline.enabled = True
days_before=3
date_field=due_date
date_format=%Y-%m-%d

[ticket-custom]
due_date = text
due_date.date = true
due_date.label = Due Date
due_date.value = YYYY-MM-DD
due_date.date_empty = true

[datefield]
format = ymd 
separator = -
first_day = 1

Bundled Scheduler

Hourly scheduler

See task scheduling section.

Daily scheduler

See task scheduling section.

Weekly scheduler

See task scheduling section.

Monthly scheduler

See task scheduling section.

Cron Scheduler

Since 0.2dev_r9375 there is a cron scheduler. You can use cron syntaxe to define the schedule. Currenlty you can use

  • single value
  • range value both with - or / special character
  • special value *

example with heart_beat task

heart_beat.cron = * 0/2 * * * ? *

warning : since TracCronPlugin ticker interval is at least one minute, this means the seconds cannot be specified and so the first item of the cron expression is useless.

The cron like expression is here. Set either day-of-month or day-of-week and the other one must be '?'.

ex: *  *  *  ?  *  ?  *
    ┬  ┬  ┬  ┬  ┬  ┬  ┬
    │  │  │  │  │  │  └──── year (omissible)
    │  │  │  │  │  └─────── day of week (1 - 7, 1 is Monday)
    │  │  │  │  └────────── month (1 - 12)
    │  │  │  └───────────── day of month (1 - 31)
    │  │  └──────────────── hour (0 - 23)
    │  └─────────────────── min (0 - 59)
    └────────────────────── None (reserved?)

Please refer to cron documentation for more details cron syntax

Bundled Listener

Email notification of task event

This listener notify by email about task execution. You can choose the number of event sent by email by setting the value of email_task_event.limit. When the listener has received at least the number of task execution,it will send the mail. Default is 1. The value of email_task_event.recipient must be filled otherwise no mail will be sent.

Here the configuration for this listener

email_task_event.enabled = True
email_task_event.limit = 1
email_task_event.recipient = admin

Here an sample of the email :

The above task has been run by Trac Cron Plugin

task[heart_beat]
started at 0 h 47
ended at 0 h 47
success

task[heart_beat]
started at 0 h 48
ended at 0 h 48
success

task[heart_beat]
started at 0 h 49
ended at 0 h 49
success

Since 0.2dev_r9385 you can use email_task_event.only_error = True to send email only on error.

Recent Changes

[12591] by t2y on 2013-02-04 09:50:52
added TracCronPlugin-0.2 version
[12590] by t2y on 2013-02-04 09:50:25
added TracCronPlugin-0.1 version
[12584] by t2y on 2013-02-01 14:49:13
added t2y as a maintainer

Author/Contributors

Author: tbressure
Maintainer: t2y
Contributors:

Last modified 7 months ago Last modified on Feb 11, 2014 1:45:04 PM

Attachments (2)

Download all attachments as: .zip