cocoon-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Kavanagh <>
Subject Re: Background Task Management
Date Mon, 14 Apr 2003 13:53:12 GMT
As I'm using it, I'm tweaking things to work better. Right now, the 
background pipeline gets parameters from the pipeline that contained the 
action that launched the thread. Because I'm not using cocoon-2.1, I 
haven't launched background pipelines via timer. I need some way to get 
a SourceResolver and 2.1 is supposed to make that available from the 
ComponenetManager. So, I haven't resolved that issue yet. Right now, I'm 
also leaving it up to the task to deliver some results in a form the 
rest of the app can use. This could be updating status in a database, 
writing a file (containing the pipeline results), sending a message (we 
have JMX based message center in our app). I'm trying to keep the task 
stuff I wrote very basic and highly configurable and flexible. That 
means I try to make as few assumptions about the task being performed as 
Well, we'll see how it goes. It would be nice if this turns into 
something I can contribute back.


Upayavira wrote:

>I've a direct need for something like this myself. I haven't read your email in detail
>(will do tomorrow).
>The approach I've been taking is to gradually bring the command line interface up to 
>speed. Then, when it is close enough to what I need, I'll start thinking about the 
>application that'll run it.
>>>From my cursory look, I wonder if there isn't a lot of similarity with Ant in
your doc - 
>might it be easier to build upon Ant than to start from scratch?
>Will try to say more tomorrow.
>>The following is from a doc I wrote about some code I put together to
>>handle background thread processing in cocoon apps. I wonder if there
>>is enough need for something like this to consider giving it back to
>>the community. I'm including the doc instead of code because it is
>>easier to give an overview that way. I'd really like to hear back
>>about this (especially from those who drive cocoon development).
>>The GenericTaskManager is a class that controls some number of user
>>defined tasks. These tasks are initiated by firing an event, or by
>>time trigger. This document describes the architecture of this system
>>and how it fits into a cocoon application.
>>Design Overview
>>This package has been designed to integrate with a cocoon application
>>and provide a way to kick of background tasks and have  cron-like 
>>functionality, but in java. Avalon classes and interfaces were
>>utilized heavily in the design. Tasks and their time triggers are
>>defined in a tasks.xconf file. Two actions are provided that can also
>>start background tasks.
>>Configuration File
>>The tasks.xconf file lists tasks, optional time triggers and optional
>>configuration particular to the task. Here s an example.
>><?xml version="1.0" encoding="UTF-8"?>
>><tasks version="1.0">
>><task name="test1" classname="">
>><!-- Several time elements can be here to specify multiple
>>invocation criteria -->
>><time type="periodic"> <!-- values in milliseconds -->
>><!-- this task happens at 1 am, every day -->
>><time type="cron">
>><day week="false"/>
>><!-- this block contains config details specific to this task -->
>><task-config> <test>hey!</test> </task-config> </task>
<!--This task
>>is a typical event driven task, with no special configuration -->
>><task name="FileUpload"
>>classname="" /> </task-list>
>></tasks> Notice that a task can have more than one time trigger, for
>>more complex (or confusing) invocation needs. A task might allow
>>custom configuration. In that case, it is able to process the
>>configuration information from the <task-config> element (and elements
>>contained within).
>>GenericTask interface
>>This interface must be implemented by any class that is defined as a
>>task in the xconf file. It contains configuration, runtime setup and
>>execution methods.
>>public interface GenericTask extends Configurable, LogEnabled, 
>>Parameterizable, Target {
>>* Used to set up the task
>>public void configure(Configuration configuration) throws 
>>* Used to pass info to the task
>>public void parameterize(Parameters parameters) throws
>>* Sets source that represents a cocoon pipeline to invoke
>>public void setSource(Source source);
>>* Thie method is from the Avalon Target interface. It allows
>>* this task to be scheduled (to get time or interval notifications).
>>*/ public void targetTriggered(String triggerName); }
>>The imports have been omitted for clarity. The Configuration object
>>passed in represents the <task-config> element in the tasks.xconf
>>file. The Parameters passed in come from the URL invoking the action
>>and from sitemap parameters. The Source is a special configuration
>>item that represents a connection to a sitemap pipeline. If a
>>parameter called  cocoonURL  has been defined, the UploadTaskAction
>>will use the SourceResolver to resolve that URL and create a Source
>>object to be passed to the task. This allows a task to run a cocoon
>>pipeline as a background task. I d like to point out how powerful
>>these features make this! ?
>>The targetTriggered() method comes from the Target interface. This is
>>normally used by the Avalon scheduling code, but we also use it for
>>traditional event invocation. Setting the parameters and souce at
>>invocation time make up for not passing a data-laden event into the
>>invocation method.
>>The Actions
>>There are two actions (the might get re-factored into one). The 
>>StartTaskAction is a simple action that doesn t try to resolve the
>>cocoonURL. It simply fires an event with the taskname and parameters
>>to the GenericTaskManger. The UploadTaskAction attempts to resolve the
>>cocoonURL and passes the resulting Source to the task when firing the
>>To use the action(s), define them in the <map:components> section.
>><map:action name= task 
>>src= /> <map:action
>>name= upload-task  src= />
>>An example pipeline that uses the action looks like this.
>><map:match pattern="mbr/upload2">
>><map:act type="upload-task">
>><map:parameter name="name" value="FileUpload" />
>><map:parameter name="cocoonURL" value="cocoon://mbr/upload-int" />
>><map:read src="html/upload-good.html" mime-type="text/html"/>
>></map:act> <map:read src="html/upload-error.html"
>>mime-type="text/html"/> </map:match>
>>The  name  parameter refers to the task name from the tasks.xconf
>>Stuff in cocoon.xconf
>>There are two components that need to be added into the cocoon.xconf
>>file. One being the GenericTaskManager and the other an Avalon thread
>>manager. The thread manager is use to thread off timed and event
>>tasks. This stuff goes right before the </cocoon> tag.
>><!-- ======================= ThreadManager ===========================
>>--> <component
>><thread-group> <name>default</name> <is-daemon>false</is-daemon>
>><min-threads>5</min-threads> <max-threads>10</max-threads>
>></thread-group> </component> <!-- ======================= TaskManager
>>=========================== --> <component
>>Task Example
>>This is the complete FileUploadTask I ve written to invoke a cocoon
>>pipeline that imports a datafile into a database. Notice the
>>ContentHandler that looks for any error elements in the resulting XML.
>>import org.xml.sax.Attributes;
>>import org.xml.sax.helpers.DefaultHandler;
>>import org.apache.avalon.framework.configuration.Configurable;
>>import org.apache.avalon.framework.configuration.Configuration;
>>import org.apache.avalon.framework.parameters.ParameterException;
>>import org.apache.avalon.framework.parameters.Parameterizable; import
>>import org.apache.cocoon.environment.Source;
>>public class FileUploadTask extends AbstractTask {
>>private String filename;
>>private boolean errorReceived;
>>* Used to pass info to the task.
>>public void parameterize(Parameters parameters) throws
>>ParameterException { this.filename =
>>parameters.getParameter("uploadfile"); }
>>* Thie method is from the Avalon Target interface. It allows
>>* this task to be scheduled (to get time or interval notifications).
>>*/ public void targetTriggered(String triggerName) { try {
>>getLogger().debug("going to call pipeline to process file :
>>"+this.filename); try { DefaultHandler handler = new MyHandler();
>>this.errorReceived = false; source.toSAX(handler); if (errorReceived)
>>getLogger().error("Got error on data insert!"); else
>>getLogger().error("Looks like data insert worked!"); } finally { if
>>(source != null) source.recycle(); } } catch (Exception ex) {
>>getLogger().error("Couldn't run pipeline...", ex); } }
>>class MyHandler extends DefaultHandler {
>>public void startElement(String uri, String localName, String qName,
>>Attributes attributes) { if (localName.indexOf("error")>-1)
>>errorReceived = true; } } }
>>To unsubscribe, e-mail: For
>>additional commands, e-mail:
>To unsubscribe, e-mail:
>For additional commands, e-mail:

View raw message