org.oddjob.scheduling
Class Timer

java.lang.Object
  extended by org.oddjob.framework.BaseComponent
      extended by org.oddjob.framework.BasePrimary
          extended by org.oddjob.scheduling.ScheduleBase
              extended by org.oddjob.scheduling.TimerBase
                  extended by org.oddjob.scheduling.Timer
All Implemented Interfaces:
Serializable, Runnable, ArooaContextAware, ArooaSessionAware, PropertyChangeNotifier, Iconic, LogEnabled, Resetable, Stateful, Stoppable, Structural

public class Timer
extends TimerBase

Description

Provides a simple timer for periodic or once only execution of the child job.

Schedules

Once only execution: Recurring executions: Holidays:

Missed Executions

If Oddjob is running with a persister missed executions fire immediately one after the other until all missed executions have run.

This can be overridden with the skipMissedRuns property.

If a timer is started after the initial execution time but within the interval of the schedule - execution will happen immediately. Extended intervals are created using the from properties instead of the at/in/on properties of schedules.

Changing The Next Due Time

There are two ways to change the next due date of a timer. They both require that the timer has been started but is not yet executing, and they both involve dynamically setting properties of the job which can be done via the 'Job' -> 'Set Property' menu item in Oddjob Explorer or via the SetJob job within Oddjob.

The first method is to set the next due date directly with the nextDue property. The existing timer is cancelled and the job rescheduled to run at this time. If the time is in the past, the job will run immediately.

The second method is to set the the reschedule property with a date and time. The next due date is calculated by applying the date and time the schedule. This is particularly useful for advancing a timer.

Retrying Failed Jobs

Nest a Retry job.

Recording the Outcome of Runs

Nest an ArchiveJob.

Distributed Scheduling

Nest a GrabJob.

For More Information

For more information see the Scheduling section of the User Guide.

Example

A Timer that runs at 10am each day, Monday to Friday.
<oddjob>
    <job>
        <scheduling:timer id="timer" xmlns:scheduling="http://rgordon.co.uk/oddjob/scheduling" xmlns:schedules="http://rgordon.co.uk/oddjob/schedules">
            <schedule>
                <schedules:weekly from="Monday" to="Friday">
                    <refinement>
                        <schedules:daily at="10:00"/>
                    </refinement>
                </schedules:weekly>
            </schedule>
            <job>
                <echo id="work">Doing some work at ${timer.current.fromDate}</echo>
            </job>
        </scheduling:timer>
    </job>
</oddjob>

Example

Run once at 10am or any time after.
<oddjob>
    <job>
        <sequential>
            <jobs>
                <echo id="big-report" name="Pretend this is a Long Running Report">Meaning of Life: 42</echo>
                <scheduling:timer id="timer" xmlns:scheduling="http://rgordon.co.uk/oddjob/scheduling">
                    <schedule>
                        <schedules:time from="10:00" xmlns:schedules="http://rgordon.co.uk/oddjob/schedules"/>
                    </schedule>
                    <job>
                        <echo name="Pretend this Forwards the Long Running Report">Emailing: ${big-report.text}</echo>
                    </job>
                </scheduling:timer>
            </jobs>
        </sequential>
    </job>
</oddjob>
If the report completes before 10am the timer will schedule it to be e-mailed at 10am. If the report completes after 10am it is e-mailed immediately.

Example

Use a timer to stop a long running job.
<oddjob>
    <job>
        <sequential id="main" name="Stop Overdue Job">
            <jobs>
                <scheduling:timer id="timer" xmlns:scheduling="http://rgordon.co.uk/oddjob/scheduling">
                    <schedule>
                        <schedules:count count="1" xmlns:schedules="http://rgordon.co.uk/oddjob/schedules">
                            <refinement>
                                <schedules:after>
                                    <schedule>
                                        <schedules:interval interval="00:00:10"/>
                                    </schedule>
                                </schedules:after>
                            </refinement>
                        </schedules:count>
                    </schedule>
                    <job>
                         <stop job="${long-job}" name="Stop Long Running Job"/>
                    </job>
                </scheduling:timer>
                <wait id="long-job" name="A Long Running Job"/>
            </jobs>
        </sequential>
    </job>
</oddjob>
The job will be stopped after 10 seconds. If the job has already completed the stop will have no affect.

Example

Manually setting the next due date of the timer. When the set job is run manually the job will be schedule to run at the new time.
<oddjob>
    <job>
        <sequential>
            <jobs>
                <scheduling:timer id="timer" xmlns:scheduling="http://rgordon.co.uk/oddjob/scheduling">
                    <schedule>
                        <schedules:date on="9999-12-31" xmlns:schedules="http://rgordon.co.uk/oddjob/schedules"/>
                    </schedule>
                    <clock>
                        <value value="${clock}"/>
                    </clock>
                    <job>
                        <echo id="echo">Running at ${timer.current.fromDate}</echo>
                    </job>
                </scheduling:timer>
                <folder>
                    <jobs>
                        <set id="set">
                            <values>
                                <date date="2012-12-27 08:02" key="timer.nextDue"/>
                            </values>
                        </set>
                    </jobs>
                </folder>
            </jobs>
        </sequential>
    </job>
</oddjob>
Note that the current interval property is not changed, so the echo job shows 'Running at 9999-12-31 00:00:00.000'.

Example

Manually rescheduling the timer. When the set job is run manually, the timer will advance to it's next scheduled slot.
<oddjob>
    <job>
        <sequential>
            <jobs>
                <scheduling:timer id="timer" xmlns:scheduling="http://rgordon.co.uk/oddjob/scheduling">
                    <schedule>
                        <schedules:daily at="23:00" xmlns:schedules="http://rgordon.co.uk/oddjob/schedules"/>
                    </schedule>
                    <clock>
                        <value value="${clock}"/>
                    </clock>
                    <job>
                        <echo id="echo">Running at ${timer.current.fromDate}</echo>
                    </job>
                </scheduling:timer>
                <folder>
                    <jobs>
                        <set id="set">
                            <values>
                                <date date="TOMORROW" key="timer.reschedule">
                                    <clock>
                                        <value value="${clock}"/>
                                    </clock>
                                </date>
                            </values>
                        </set>
                    </jobs>
                </folder>
            </jobs>
        </sequential>
    </job>
</oddjob>
Note that the unlike above, current interval property changes when the time is rescheduled.
See Also:
Serialized Form
Author:
Rob Gordon.

Field Summary
 
Fields inherited from class org.oddjob.scheduling.TimerBase
contextData
 
Fields inherited from class org.oddjob.scheduling.ScheduleBase
begun, childHelper, childStateReflector, stateHandler, stop, structuralState
 
Fields inherited from class org.oddjob.framework.BaseComponent
iconHelper
 
Constructor Summary
Timer()
           
 
Method Summary
protected  void begin()
          Sub classes must override this to submit the first execution.
protected  IntervalTo getLimits()
          Implementation provided by sub classes so limits are available in TimerBase.scheduleFrom(Date).
protected  StateOperator getStateOp()
          Sub classes provide the state operator that is used to calculate the subclasses completion state.
 boolean isHaltOnFailure()
           
 boolean isSkipMissedRuns()
           
protected  void rescheduleOn(State state)
          Implementation provided by sub classes to decide how to reschedule based on the state of the child job.
protected  void reset(Resetable job)
          Implementation provided by sub classes to decide what kind of reset to send to the child.
 void setHaltOnFailure(boolean haltOnFailure)
           
 void setSkipMissedRuns(boolean skipMissedRuns)
           
 
Methods inherited from class org.oddjob.scheduling.TimerBase
CancelAndStopChild, getClock, getCurrent, getLastDue, getNextDue, getSchedule, getTimeZone, internalSetNextDue, onReset, onStop, postStop, scheduleFrom, setClock, setJob, setNextDue, setReschedule, setSchedule, setScheduleExecutorService, setTimeZone
 
Methods inherited from class org.oddjob.scheduling.ScheduleBase
addStructuralListener, fireDestroyedState, getStateChanger, hardReset, onDestroy, removeStructuralListener, run, setStateStartingAndIconSleeping, softReset, stateHandler, stop
 
Methods inherited from class org.oddjob.framework.BasePrimary
configure, getName, logger, logger, loggerName, save, setName, toString
 
Methods inherited from class org.oddjob.framework.BaseComponent
addIconListener, addPropertyChangeListener, addStateListener, configure, destroy, firePropertyChange, getArooaSession, iconForId, initialise, lastStateEvent, onConfigured, onInitialised, removeIconListener, removePropertyChangeListener, removeStateListener, save, setArooaContext, setArooaSession
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.oddjob.Stateful
addStateListener, lastStateEvent, removeStateListener
 

Constructor Detail

Timer

public Timer()
Method Detail

getStateOp

protected StateOperator getStateOp()
Description copied from class: ScheduleBase
Sub classes provide the state operator that is used to calculate the subclasses completion state.

Specified by:
getStateOp in class ScheduleBase
Returns:
The operator. Must not be null.

begin

protected void begin()
              throws ComponentPersistException
Description copied from class: ScheduleBase
Sub classes must override this to submit the first execution.

Overrides:
begin in class TimerBase
Throws:
ComponentPersistException

setHaltOnFailure

public void setHaltOnFailure(boolean haltOnFailure)

isHaltOnFailure

public boolean isHaltOnFailure()

isSkipMissedRuns

public boolean isSkipMissedRuns()

setSkipMissedRuns

public void setSkipMissedRuns(boolean skipMissedRuns)

getLimits

protected IntervalTo getLimits()
Description copied from class: TimerBase
Implementation provided by sub classes so limits are available in TimerBase.scheduleFrom(Date).

Specified by:
getLimits in class TimerBase
Returns:
The limits, or null. Retry has limits, timer doesn't.

rescheduleOn

protected void rescheduleOn(State state)
                     throws ComponentPersistException
Description copied from class: TimerBase
Implementation provided by sub classes to decide how to reschedule based on the state of the child job.

Specified by:
rescheduleOn in class TimerBase
Parameters:
state - The completion state of the child job.
Throws:
ComponentPersistException

reset

protected void reset(Resetable job)
Description copied from class: TimerBase
Implementation provided by sub classes to decide what kind of reset to send to the child. Timer sends a hard reset, Retry sends a soft reset.

Specified by:
reset in class TimerBase
Parameters:
job - The child job that will be reset.