Personal tools
You are here: Home Idea Workspace Imp Documentation Job System
Document Actions

Job System

by rmoskal last modified 2006-07-25 07:39

Describes the workings of the job system of the application. This is a good place to start.

Almost all operations on releases are carried out by a job execution subsystem.  This system works by implementing the command pattern. So at the highest level, all the tasks in the system implement the ITask interface which has one primary method execute(Shipment aShipment, contextMap).

Job System

When a task is executed it is passed an instance of a Shipment class, which is the basic unit of work for the application.  They are also passed a hashtable which acts as a context for the tasks.  The context contains additional information needed to carry out processing, and provides a means for communicating among tasks.  Each task pulls what it needs from the context, obviating the need for the system to know a task's exact requirements.  The job system does pass some commonly needed information to every task.
Most tasks subclass either DispatchingTask or TraversingTask.

Dispatching Task

Dispatching task is passed a list of other tasks from the spring context, so its primary job is to execute a series of tasks.  This is usually specified in the spring context file like so:

    <bean id="connect.Shipper" class="com.idea.imp.service.common.DispatchingTask"> 
<constructor-arg><ref bean="applicationSettingsBean"/></constructor-arg>
<constructor-arg>
<list>
<bean class="com.idea.imp.service.shipper.DirrectoryShipper">
<constructor-arg>
<bean class="com.idea.imp.service.shipper.protocols.FTPTransferrer">
<constructor-arg><value>localhost</value></constructor-arg>
<constructor-arg><value></value></constructor-arg>
<constructor-arg><value>5000</value></constructor-arg>
</bean>
</constructor-arg>
</bean>
<bean class="com.idea.imp.service.shipper.ShipperFinalizer">
<constructor-arg>
<bean class="com.idea.imp.helpers.MockBaseDAO"></bean>
</constructor-arg>
<constructor-arg><value>3</value></constructor-arg>
</bean>
<bean class="com.idea.imp.service.shipper.DirectoryCleaner"/>
</list>
</constructor-arg>
</bean>

The Dispatching task is normally used just like this. There are a few concrete classes that implement it, but usually concrete tasks are implemented by TraversingTask.

TraversingTask

Most jobs in the system descend from TraversingTask.  TraversingTask implements the vistor pattern to traverse all the nodes in a shipment: shipment, release(s), volume(s), track(s).  As a convenience the vistor also provides a method for visting each and every node of the graph in turn.

public interface IShipmentVisitor {

public void visitShipment(Shipment aShipment, Map context, Map decoratedObject) throws Exception;
public void visitRelease(Release aRelease, Map context, Map decoratedObject)throws Exception;
public void vistVolume(Volume aVolume, Map context, Map decoratedObject)throws Exception;
public void visitTrack(Track aTrack, Map context, Map decoratedObject)throws Exception;
public void visitAll(BaseDomain o, Map context, Map decoratedObject)throws Exception;

public boolean getCausesFailure();
public boolean getStopProcessingOnFailure();

}

Using the visitor pattern eliminates writing endless nested loops to traverse the object tree. Each node is visted in turn, so far we have implemented a PostfixTraversal and a PrefixTraversal. As each node is visted we provide the task with addition information it might require.  This is located on another Map, decoratedObject. This allows us to decorate each node with Shipment, Release, Volume, and track specific information.  This info is kept on the global job context (keyed by each objects uuid primary key), but we pass it here for convenience.

Inside the  each traversal, we can also make sure that each task plays nicely withing our error handling schema.  By default a TraversingTask causes the job within which it runs to fail.  When operating on a track, volume, or release, any exception thrown marks that release as failed  (we place a PackagerHelpers.RELEASE_FAILURE on the decoratedObect for the current release). If the exception occurrs when visiting the shipment, then the entire shipment is marked as failed (by marking the shipment decoratedObject with key of PackagerHelpers.SHIPMENT_FAILURE). Whether or not a task fails is governed by the CausesFailure property in IShipmentVisitor

In a similar fashion the StopProcessingOnFailure property governs whether the job should halt on error.  This defaults to false. The values for both CausesFailure and StopProcessingOnFailure are normally overridden in the Spring configuration file.

Lastly, the TraversingTask is normally provided its traversal by the DispatchingTask in which it is embedded.  Sometimes you want to override this propert, such as when you need a different traversal (postfix vs. prefix) to get something done.


Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: