This looks pretty cool. I like the idea of using the Servlet interface instead of Callable/Runnable.
I have two comments: 1) The request/response pair passed to the servlet should be entirely synthetic. This is true in general AFAIK[1]; in Sling it is especially true because request.getResourceResolver() will return a closed resource resolver. 2) Even with synthetic request/response objects, I suspect that not all servlets are going to work in the background (or s/going to/should/). Thus, what about using a marker interface on the servlet to declare that it should be run in the background. Or... to declare that it can be run in the background. Justin [1] that is, the ServletRequest and ServletResponse objects are not meant to be used outside of the request thread owned by the servlet container. On 7/13/10 7:58 AM, [email protected] wrote: > Author: bdelacretaz > Date: Tue Jul 13 11:58:51 2010 > New Revision: 963686 > > URL: http://svn.apache.org/viewvc?rev=963686&view=rev > Log: > SLING-550 - first shot at background servlets engine, works for some simple > cases, no job control yet > > Added: > sling/trunk/contrib/extensions/bgservlets/ (with props) > sling/trunk/contrib/extensions/bgservlets/pom.xml (with props) > sling/trunk/contrib/extensions/bgservlets/src/ > sling/trunk/contrib/extensions/bgservlets/src/main/ > sling/trunk/contrib/extensions/bgservlets/src/main/java/ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/ > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java > (with props) > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java > (with props) > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java > (with props) > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java > (with props) > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java > (with props) > > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java > (with props) > > Propchange: sling/trunk/contrib/extensions/bgservlets/ > ------------------------------------------------------------------------------ > --- svn:ignore (added) > +++ svn:ignore Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,13 @@ > +target > +bin > +derby.log > +*.iml > +*.ipr > +*.iws > +.settings > +.project > +.classpath > +.externalToolBuilders > +maven-eclipse.xml > + > + > > Added: sling/trunk/contrib/extensions/bgservlets/pom.xml > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/pom.xml?rev=963686&view=auto > ============================================================================== > --- sling/trunk/contrib/extensions/bgservlets/pom.xml (added) > +++ sling/trunk/contrib/extensions/bgservlets/pom.xml Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,94 @@ > +<?xml version="1.0" encoding="UTF-8"?> > + <!-- > + Licensed to the Apache Software Foundation (ASF) under one or more > + contributor license agreements. See the NOTICE file distributed with > + this work for additional information regarding copyright ownership. > + The ASF licenses this file to you under the Apache License, Version > + 2.0 (the "License"); you may not use this file except in compliance > + with the License. You may obtain a copy of the License at > + > + http://www.apache.org/licenses/LICENSE-2.0 Unless required by > + applicable law or agreed to in writing, software distributed under > + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES > + OR CONDITIONS OF ANY KIND, either express or implied. See the > + License for the specific language governing permissions and > + limitations under the License. > + --> > +<project xmlns="http://maven.apache.org/POM/4.0.0" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 > http://maven.apache.org/maven-v4_0_0.xsd"> > + > + <modelVersion>4.0.0</modelVersion> > + <parent> > + <groupId>org.apache.sling</groupId> > + <artifactId>sling</artifactId> > + <version>9</version> > + <relativePath>../../../parent/pom.xml</relativePath> > + </parent> > + > + <artifactId>org.apache.sling.bgservlets</artifactId> > + <version>0.0.1-SNAPSHOT</version> > + <packaging>bundle</packaging> > + > + <name>Apache Sling Background Servlets Engine</name> > + <description> > + Allows scripts and servlets to run as background tasks > + which can be suspended, resumed, stopped and restarted. > + </description> > + > + <scm> > + > <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/bgservlets</connection> > + > <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/bgservlets</developerConnection> > + > <url>http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/bgservlets</url> > + </scm> > + > + <build> > + <plugins> > + <plugin> > + <groupId>org.apache.felix</groupId> > + <artifactId>maven-scr-plugin</artifactId> > + </plugin> > + <plugin> > + <groupId>org.apache.felix</groupId> > + <artifactId>maven-bundle-plugin</artifactId> > + <extensions>true</extensions> > + <configuration> > + <instructions> > + <Export-Package>org.apache.sling.bgservlets</Export-Package> > + > <Private-Package>org.apache.sling.bgservlets.impl.*</Private-Package> > + </instructions> > + </configuration> > + </plugin> > + </plugins> > + </build> > + > + <dependencies> > + <dependency> > + <groupId>org.osgi</groupId> > + <artifactId>org.osgi.core</artifactId> > + </dependency> > + <dependency> > + <groupId>org.osgi</groupId> > + <artifactId>org.osgi.compendium</artifactId> > + </dependency> > + <dependency> > + <groupId>org.apache.felix</groupId> > + <artifactId>org.apache.felix.scr.annotations</artifactId> > + <version>1.2.0</version> > + <scope>compile</scope> > + </dependency> > + <dependency> > + <groupId>org.apache.sling</groupId> > + <artifactId>org.apache.sling.api</artifactId> > + <version>2.0.8</version> > + <scope>provided</scope> > + </dependency> > + <dependency> > + <groupId>javax.servlet</groupId> > + <artifactId>servlet-api</artifactId> > + </dependency> > + <dependency> > + <groupId>org.slf4j</groupId> > + <artifactId>slf4j-api</artifactId> > + </dependency> > + </dependencies> > +</project> > \ No newline at end of file > > Propchange: sling/trunk/contrib/extensions/bgservlets/pom.xml > ------------------------------------------------------------------------------ > svn:eol-style = native > > Added: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java?rev=963686&view=auto > ============================================================================== > --- > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java > (added) > +++ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java > Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,28 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.sling.bgservlets; > + > +/** Service that executes Runnables, will later allow > + * them to be suspended, resumed, stopped and restarted. > + */ > +public interface ExecutionEngine { > + > + /** Add a job to the execution queue */ > + void queueForExecution(Runnable job); > +} > \ No newline at end of file > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision Rev URL > > Added: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java?rev=963686&view=auto > ============================================================================== > --- > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java > (added) > +++ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java > Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,91 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.sling.bgservlets.impl; > + > +import java.io.IOException; > + > +import javax.servlet.Filter; > +import javax.servlet.FilterChain; > +import javax.servlet.FilterConfig; > +import javax.servlet.ServletException; > +import javax.servlet.ServletRequest; > +import javax.servlet.ServletResponse; > +import javax.servlet.http.HttpServletRequest; > +import javax.servlet.http.HttpServletResponse; > + > +import org.apache.felix.scr.annotations.Component; > +import org.apache.felix.scr.annotations.Properties; > +import org.apache.felix.scr.annotations.Property; > +import org.apache.felix.scr.annotations.Reference; > +import org.apache.felix.scr.annotations.Service; > +import org.apache.sling.bgservlets.ExecutionEngine; > +import org.slf4j.Logger; > +import org.slf4j.LoggerFactory; > + > +/** Filter that runs the current request in the background > + * if specific request parameters are set. > + * TODO: define the position of this filter in the chain, > + * and how do we enforce it? > + */ > +...@component > +...@service > +...@properties({ > + @Property(name="filter.scope", value="request"), > + @Property(name="filter.order", intValue=java.lang.Integer.MIN_VALUE) > +}) > +public class BackgroundServletStarterFilter implements Filter{ > + > + private final Logger log = LoggerFactory.getLogger(getClass()); > + > + @Reference > + private ExecutionEngine executionEngine; > + > + /** > + * Request runs in the background if this request parameter is present > + * TODO should be configurable, and maybe use other decision methods */ > + public static final String BG_PARAM = "sling:bg"; > + > + public void doFilter(final ServletRequest sreq, final ServletResponse > sresp, > + final FilterChain chain) throws IOException, > ServletException { > + if(!(sreq instanceof HttpServletRequest)) { > + throw new ServletException("request is not an > HttpServletRequest: " + sresp.getClass().getName()); > + } > + if(!(sresp instanceof HttpServletResponse)) { > + throw new ServletException("response is not an > HttpServletResponse: " + sresp.getClass().getName()); > + } > + final HttpServletRequest request = (HttpServletRequest)sreq; > + final HttpServletResponse response = > (HttpServletResponse)sresp; > + if(sreq.getParameter(BG_PARAM) != null) { > + final FilterChainExecutionJob job = new > FilterChainExecutionJob(chain, request, response); > + log.debug("{} request parameter present, running > request in the background using {}", BG_PARAM, job); > + executionEngine.queueForExecution(job); > + > + // TODO not really an error, should send a nicer message > + response.sendError(HttpServletResponse.SC_ACCEPTED, > "Running request in the background using " + job); > + } else { > + chain.doFilter(sreq, sresp); > + } > + } > + > + public void destroy() { > + } > + > + public void init(FilterConfig cfg) throws ServletException { > + } > +} > \ No newline at end of file > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision Rev URL > > Added: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java?rev=963686&view=auto > ============================================================================== > --- > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java > (added) > +++ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java > Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,78 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.sling.bgservlets.impl; > + > +import java.io.IOException; > +import java.io.PrintWriter; > + > +import javax.servlet.ServletException; > + > +import org.apache.felix.scr.annotations.Component; > +import org.apache.felix.scr.annotations.Property; > +import org.apache.felix.scr.annotations.Service; > +import org.apache.sling.api.SlingHttpServletRequest; > +import org.apache.sling.api.SlingHttpServletResponse; > +import org.apache.sling.api.servlets.SlingSafeMethodsServlet; > + > +/** Servlet used for interactive testing of the background > + * servlets engine. > + * TODO remove once we have better tests. > + */ > +...@component > +...@service > +...@suppresswarnings("serial") > +...@property(name="sling.servlet.paths", value="/system/bgservlets/test") > +public class BackgroundTestServlet extends SlingSafeMethodsServlet { > + > + @Override > + protected void doGet(SlingHttpServletRequest request, > + SlingHttpServletResponse response) throws > ServletException, > + IOException { > + response.setContentType("text/plain"); > + final PrintWriter w = response.getWriter(); > + > + final int cycles = getIntParam(request, "cycles", 10); > + final int interval = getIntParam(request, "interval", 1); > + final int flushEvery = getIntParam(request, "flushEvery", 2); > + > + for(int i=1; i <= cycles; i++) { > + if(i % flushEvery == 0) { > + w.println("Flushing output"); > + w.flush(); > + } > + w.printf("Cycle %d of %d\n", i, cycles); > + try { > + Thread.sleep(interval * 1000); > + } catch(InterruptedException iex) { > + throw new > ServletException("InterruptedException", iex); > + } > + } > + w.println("All done."); > + w.flush(); > + } > + > + private int getIntParam(SlingHttpServletRequest request, String name, > int defaultValue) { > + int result = defaultValue; > + final String str = request.getParameter(name); > + if(str != null) { > + result = Integer.parseInt(str); > + } > + return result; > + } > +} > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision Rev URL > > Added: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java?rev=963686&view=auto > ============================================================================== > --- > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java > (added) > +++ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java > Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,74 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.sling.bgservlets.impl; > + > +import java.util.concurrent.ArrayBlockingQueue; > +import java.util.concurrent.BlockingQueue; > +import java.util.concurrent.Executor; > +import java.util.concurrent.RejectedExecutionHandler; > +import java.util.concurrent.ThreadPoolExecutor; > +import java.util.concurrent.TimeUnit; > + > +import org.apache.felix.scr.annotations.Component; > +import org.apache.felix.scr.annotations.Service; > +import org.apache.sling.api.SlingException; > +import org.apache.sling.bgservlets.ExecutionEngine; > +import org.osgi.service.component.ComponentContext; > + > +/** Simple ExecutionEngine > + * TODO should use Sling's thread pool, and check synergies > + * with scheduler services */ > +...@component > +...@service > +public class ExecutionEngineImpl implements ExecutionEngine { > + > + private Executor executor; > + > + @SuppressWarnings("serial") > + public static class QueueFullException extends SlingException { > + QueueFullException(Runnable r) { > + super("Execution queue is full, cannot execute " + r); > + } > + } > + > + public void activate(ComponentContext context) { > + // TODO configurable! > + final int corePoolSize = 2; > + int maximumPoolSize = 2; > + long keepAliveTime = 30; > + TimeUnit unit = TimeUnit.SECONDS; > + BlockingQueue<Runnable> workQueue = new > ArrayBlockingQueue<Runnable>(4); > + RejectedExecutionHandler handler = new RejectedExecutionHandler() { > + public void rejectedExecution(Runnable r, > ThreadPoolExecutor executor) { > + throw new QueueFullException(r); > + } > + }; > + executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, > keepAliveTime, unit, workQueue, handler); > + } > + > + public void deactivate(ComponentContext context) { > + // TODO how to shutdown executor? > + executor = null; > + } > + > + public void queueForExecution(Runnable job) { > + // TODO wrap job in our own Runnable to detect start/end etc. > + executor.execute(job); > + } > +} > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision Rev URL > > Added: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java?rev=963686&view=auto > ============================================================================== > --- > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java > (added) > +++ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java > Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,68 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.sling.bgservlets.impl; > + > +import java.io.IOException; > + > +import javax.servlet.FilterChain; > +import javax.servlet.http.HttpServletRequest; > +import javax.servlet.http.HttpServletResponse; > + > +import org.slf4j.Logger; > +import org.slf4j.LoggerFactory; > + > +/** Runnable that executes a FilterChain, using > + * a ServletResponseWrapper to capture the output. > + */ > +class FilterChainExecutionJob implements Runnable { > + private final Logger log = LoggerFactory.getLogger(getClass()); > + private final FilterChain chain; > + private final ServletResponseWrapper response; > + > + // TODO is it ok to keep a reference to the request until run() is > called?? > + private final HttpServletRequest request; > + > + FilterChainExecutionJob(FilterChain chain, HttpServletRequest request, > HttpServletResponse hsr) throws IOException { > + this.chain = chain; > + this.request = request; > + response = new ServletResponseWrapper(hsr); > + } > + > + public String toString() { > + return "Background request job: " + response; > + } > + > + public void run() { > + log.info("{} execution starts", this); > + try { > + chain.doFilter(request, response); > + } catch(Exception e) { > + // TODO report errors in the background job's output > + log.error("chain.doFilter failed", e); > + } finally { > + try { > + response.cleanup(); > + } catch(IOException ioe) { > + // TODO report errors in the background job's > output > + log.error("ServletResponseWrapper cleanup > failed", ioe); > + } > + } > + log.info("{} execution ends", this); > + } > +} > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision Rev URL > > Added: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java > URL: > http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java?rev=963686&view=auto > ============================================================================== > --- > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java > (added) > +++ > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java > Tue Jul 13 11:58:51 2010 > @@ -0,0 +1,93 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.sling.bgservlets.impl; > + > +import java.io.File; > +import java.io.FileOutputStream; > +import java.io.IOException; > +import java.io.OutputStream; > +import java.io.OutputStreamWriter; > +import java.io.PrintWriter; > + > +import javax.servlet.ServletOutputStream; > +import javax.servlet.http.HttpServletResponse; > +import javax.servlet.http.HttpServletResponseWrapper; > + > +/** Wraps an HttpServletResponse for background processing */ > +class ServletResponseWrapper extends HttpServletResponseWrapper { > + > + private final String outputPath; > + private final ServletOutputStream stream; > + private final PrintWriter writer; > + > + static class CustomOutputStream extends ServletOutputStream { > + > + private final OutputStream os; > + > + CustomOutputStream(OutputStream os) { > + this.os = os; > + } > + > + @Override > + public void write(int b) throws IOException { > + os.write(b); > + } > + > + @Override > + public void close() throws IOException { > + os.close(); > + } > + > + @Override > + public void flush() throws IOException { > + os.flush(); > + } > + > + } > + > + ServletResponseWrapper(HttpServletResponse response) throws IOException > { > + super(response); > + // TODO write output to the Sling repository. For now: just a > temp file > + final File output = > File.createTempFile(getClass().getSimpleName(), ".data"); > + output.deleteOnExit(); > + outputPath = output.getAbsolutePath(); > + stream = new CustomOutputStream(new FileOutputStream(output)); > + writer = new PrintWriter(new OutputStreamWriter(stream)); > + } > + > + public String toString() { > + return getClass().getName() + ":" + outputPath; > + } > + > + void cleanup() throws IOException { > + stream.flush(); > + stream.close(); > + } > + > + @Override > + public ServletOutputStream getOutputStream() throws IOException { > + return stream; > + } > + > + @Override > + public PrintWriter getWriter() throws IOException { > + return writer; > + } > + > +} > \ No newline at end of file > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision Rev URL > >
