Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by DavorHrg:
http://wiki.apache.org/tapestry/Tapestry5HowToRunTaskInThread

New page:
Questions about running tasks in separate thread were asked more than few times 
on the mailing list. The code is simple but some important things must be 
considered.

Most important thing is to call !ThreadCleanupHub.cleanup() after the thread is 
finished.

Other thing is that the separate thread will have different instances of any 
threaded services and will not have any user specific data. For example if you 
load an Hibernate entity inside the request thread and pass it to the task, the 
task will get a different Hibernate Session instance and will fail if you try 
to save the instance while the task is running (in a separate thread that is)

To save you some trouble I've created a simple service that runs tasks in a 
separate thread and makes sure ThreadCleanupHub.cleanup()is called. You can 
inject it anywhere and call:
{{{#!java
_threadSource.runInThread(new Runnable(){
    public void run(){
        //do something
    }
});
}}}


interface !ThreadSource
{{{#!java
public interface ThreadSource {

    /** runs the task using default exception handler, which writes exception 
to the log */
    public abstract void runInThread(Runnable task);

    /** runs a task in a separate thread and makes sure that tapestry ioc 
resources are freed after
     * thread finishes.*/
    public abstract void runInThread(final Runnable task, final 
TaskExceptionHandler taskExceptionHandler);

}
}}}

interface !TaskExceptionHandler 
{{{#!java
public interface TaskExceptionHandler {
    public void exceptionThrown(Object task, Throwable exception);
}
}}}

implementation (you can implement it way you like it, and even add a thread 
pool)
{{{#!java

import org.apache.tapestry.ioc.services.ThreadCleanupHub;
import org.slf4j.Logger;

public class ThreadSourceImpl implements ThreadSource {

    private final ThreadCleanupHub _cleanupHub;
    private final Logger _logger;

    public ThreadSourceImpl(ThreadCleanupHub cleanupHub, Logger logger){
        _cleanupHub = cleanupHub;
        _logger = logger;
    }
    
    /* (non-Javadoc)
     * @see tapestryutil.services.ThreadSource#runInThread(java.lang.Runnable)
     */
    public void runInThread(Runnable task){
        runInThread(task,defaultTaskExceptionHandler);
    }

    /* (non-Javadoc)
     * @see tapestryutil.services.ThreadSource#runInThread(java.lang.Runnable, 
tapestryutil.services.TaskExceptionHandler)
     */
    public void runInThread(final Runnable task, final TaskExceptionHandler 
taskExceptionHandler){
        new Thread(new Runnable(){

            public void run() {
                try {
                   task.run();
                } catch (Throwable e) {
                    taskExceptionHandler.exceptionThrown(task, e);
                } finally {
                    _cleanupHub.cleanup();
                }
            }
            
        }).start();
    }
    
    /** default exception handler that writes exception to the log */
    private final TaskExceptionHandler defaultTaskExceptionHandler = new 
TaskExceptionHandler(){
        public void exceptionThrown(Object task, Throwable exception) {
            _logger.error("Task failed :"+task, exception);
        }
    };
    
}
}}}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to