Tapestry and Restlet Part 2

By Taylor
Filed Under Software 

In my previous writeup on Tapestry and Restlet, I missed something, which fortunately our integration tests turned up.

Since Tapestry is ignoring calls to our REST api, we aren’t hooked into their plumbing.  The problem here is that Tapestry stores a lot of stuff in ThreadLocal and removes it based on a Tapestry Filter.

Thus, while the result of my previous post will work in simple scenarios, one ends up with things like long running Hibernate sessions, and since Tapestry’s transaction management is a bit wonky, long running transactions as well.

To fix this problem, we need to create a Restlet Filter that will handle triggering Tapestry’s cleanup, and hook it onto our Router.  The cleanup filter:

package firstSteps.filter;
 
import org.apache.log4j.Logger;
import org.apache.tapestry5.ioc.services.PerthreadManager;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Status;
import org.restlet.routing.Filter;
 
public class CleanupFilter extends Filter {
    private PerthreadManager perthreadManager;
 
    public CleanupFilter(Context ctx, PerthreadManager perthreadManager) {
        super(ctx);
        this.perthreadManager = perthreadManager;
    }
 
    @Override
    protected void afterHandle(Request request, Response response) {
        perthreadManager.cleanup();
    }
}

To hook this onto the router would be something like the following at the end of your Restlet Application’s createRoot method.

    CleanupFilter cleanupFilter = new CleanupFilter( getContext(),
        getService(PerthreadManager.class) );
    cleanupFilter.setNext( router );
    return cleanupFilter;

Comments

Leave a Reply