# HG changeset patch # User robcast # Date 1298149272 -3600 # Node ID 755848b96fc1fe1772914b68916b47a926629d5f # Parent 02e1de41b6ba6096dd93447fa0fabf6fac12d467 first version using officially approved Servlet 3.0 async support. diff -r 02e1de41b6ba -r 755848b96fc1 client/digitallibrary/WEB-INF/web.xml --- a/client/digitallibrary/WEB-INF/web.xml Sat Feb 19 12:32:20 2011 +0100 +++ b/client/digitallibrary/WEB-INF/web.xml Sat Feb 19 22:01:12 2011 +0100 @@ -1,8 +1,10 @@ - - - + + + digilib @@ -10,14 +12,11 @@ This is the web frontend of the Digital Document Library. - + Initialiser - - The inialisation servlet (must run first). - digilib.servlet.Initialiser @@ -31,9 +30,6 @@ Scaler - - The servlet to scale the digilib images. - digilib.servlet.Scaler @@ -47,9 +43,6 @@ Texter - - The servlet for text. - digilib.servlet.Texter @@ -59,9 +52,6 @@ PDFCache - - The servlet for PDF. - digilib.servlet.PDFCache @@ -80,6 +70,14 @@ Scaler + /Scaler + + + + + Scaler + + /authenticated/servlet/Scaler/* diff -r 02e1de41b6ba -r 755848b96fc1 servlet/src/digilib/servlet/AsyncServletWorker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/AsyncServletWorker.java Sat Feb 19 22:01:12 2011 +0100 @@ -0,0 +1,80 @@ +/** + * + */ +package digilib.servlet; + +import java.io.IOException; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import digilib.image.DocuImage; +import digilib.image.ImageJobDescription; +import digilib.image.ImageOpException; +import digilib.image.ImageWorker; +import digilib.servlet.Scaler.ErrMsg; +import digilib.servlet.Scaler.Error; + +/** + * @author casties + * + */ +public class AsyncServletWorker implements Runnable { + + /** the AsyncServlet context */ + private AsyncContext asyncContext; + + /** the ImageWorker we use */ + private ImageWorker imageWorker; + + protected static Logger logger = Logger.getLogger(AsyncServletWorker.class); + private long startTime; + ErrMsg errMsgType = ErrMsg.IMAGE; + + /** + * @param dlConfig + * @param jobinfo + */ + public AsyncServletWorker(DigilibConfiguration dlConfig, + ImageJobDescription jobinfo, AsyncContext asyncContext, + ErrMsg errMsgType, long startTime) { + // set up image worker + imageWorker = new ImageWorker(dlConfig, jobinfo); + // save AsyncContext + this.asyncContext = asyncContext; + this.startTime = startTime; + this.errMsgType = errMsgType; + } + + /** + * runs the ImakeWorker and writes the image to the ServletResponse. + */ + public void run() { + // get fresh response + HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse(); + try { + // render the image + DocuImage img = imageWorker.call(); + // send image + ServletOps.sendImage(img, null, response, logger); + logger.debug("Job Processing Time: " + + (System.currentTimeMillis() - startTime) + "ms"); + } catch (ImageOpException e) { + logger.error(e.getClass() + ": " + e.getMessage()); + Scaler.digilibError(errMsgType, Error.IMAGE, null, response); + } catch (IOException e) { + logger.error(e.getClass() + ": " + e.getMessage()); + Scaler.digilibError(errMsgType, Error.FILE, null, response); + } catch (ServletException e) { + logger.error("Servlet error: ", e); + } finally { + // submit response + asyncContext.complete(); + } + + } + +} diff -r 02e1de41b6ba -r 755848b96fc1 servlet/src/digilib/servlet/Initialiser.java --- a/servlet/src/digilib/servlet/Initialiser.java Sat Feb 19 12:32:20 2011 +0100 +++ b/servlet/src/digilib/servlet/Initialiser.java Sat Feb 19 22:01:12 2011 +0100 @@ -61,7 +61,7 @@ /** DigilibConfiguration instance */ DigilibConfiguration dlConfig; - /** Executor for digilib image jobs */ + /** Executor for digilib image jobs (AsyncServletWorker doesn't return anything) */ DigilibJobCenter imageEx; /** Executor for PDF jobs */ diff -r 02e1de41b6ba -r 755848b96fc1 servlet/src/digilib/servlet/Scaler.java --- a/servlet/src/digilib/servlet/Scaler.java Sat Feb 19 12:32:20 2011 +0100 +++ b/servlet/src/digilib/servlet/Scaler.java Sat Feb 19 22:01:12 2011 +0100 @@ -3,12 +3,12 @@ import java.io.File; import java.io.IOException; import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; +import javax.servlet.AsyncContext; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -20,17 +20,18 @@ import digilib.image.DocuImage; import digilib.image.ImageJobDescription; import digilib.image.ImageOpException; -import digilib.image.ImageWorker; import digilib.io.DocuDirCache; import digilib.io.DocuDirectory; import digilib.io.ImageInput; import digilib.util.DigilibJobCenter; -@SuppressWarnings("serial") +@WebServlet(name="Scaler", urlPatterns={"/Scaler", "/servlet/Scaler/*"}, asyncSupported=true) public class Scaler extends HttpServlet { + private static final long serialVersionUID = 5289386646192471549L; + /** digilib servlet version (for all components) */ - public static final String version = "1.9.0a3"; + public static final String version = "1.9.1a2"; /** servlet error codes */ public static enum Error {UNKNOWN, AUTH, FILE, IMAGE}; @@ -54,13 +55,13 @@ DigilibJobCenter imageJobCenter; /** authentication error image file */ - File denyImgFile; + static File denyImgFile; /** image error image file */ - File errorImgFile; + static File errorImgFile; /** not found error image file */ - File notfoundImgFile; + static File notfoundImgFile; /** send files as is? */ boolean sendFileAllowed = true; @@ -183,12 +184,13 @@ accountlog.debug("request: " + request.getQueryString()); logger.debug("request: " + request.getQueryString()); - long startTime = System.currentTimeMillis(); + logger.debug("response:"+ response + " committed=" + response.isCommitted()); + final long startTime = System.currentTimeMillis(); // parse request DigilibRequest dlRequest = new DigilibRequest(request); // extract the job information - ImageJobDescription jobTicket = ImageJobDescription.getInstance(dlRequest, dlConfig); + final ImageJobDescription jobTicket = ImageJobDescription.getInstance(dlRequest, dlConfig); // type of error reporting ErrMsg errMsgType = ErrMsg.IMAGE; @@ -246,16 +248,14 @@ response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); return; } + + // worker job is done asynchronously + AsyncContext asyncCtx = request.startAsync(request, response); // create job - ImageWorker job = new ImageWorker(dlConfig, jobTicket); + AsyncServletWorker job = new AsyncServletWorker(dlConfig, jobTicket, asyncCtx, errMsgType, startTime); // submit job - Future jobResult = imageJobCenter.submit(job); - // wait for result - DocuImage img = jobResult.get(); - // send image - ServletOps.sendImage(img, null, response, logger); - logger.debug("Job Processing Time: " - + (System.currentTimeMillis() - startTime) + "ms"); + imageJobCenter.submit(job); + // we're done for now } catch (ImageOpException e) { logger.error(e.getClass() + ": " + e.getMessage()); @@ -266,15 +266,7 @@ } catch (AuthOpException e) { logger.error(e.getClass() + ": " + e.getMessage()); digilibError(errMsgType, Error.AUTH, null, response); - } catch (InterruptedException e) { - logger.error(e.getClass() + ": " + e.getMessage()); - } catch (ExecutionException e) { - logger.error(e.getClass() + ": " + e.getMessage()); - String causeMsg = e.getCause().getMessage(); - logger.error("caused by: " + causeMsg); - digilibError(errMsgType, Error.IMAGE, causeMsg, response); } - } /** @@ -285,7 +277,7 @@ * @param msg * @param response */ - public void digilibError(ErrMsg type, Error error, String msg, + public static void digilibError(ErrMsg type, Error error, String msg, HttpServletResponse response) { try { File img = null; @@ -306,13 +298,12 @@ if (msg == null) { msg = "ERROR: Other image error!"; } - img = this.errorImgFile; + img = errorImgFile; status = HttpServletResponse.SC_BAD_REQUEST; } if (response.isCommitted()) { // response already committed - logger.error("Unable to send error: " + msg); - return; + logger.warn("Response committed for error "+msg); } if (type == ErrMsg.TEXT) { ServletOps.htmlMessage(msg, response); diff -r 02e1de41b6ba -r 755848b96fc1 servlet/src/digilib/servlet/ServletOps.java --- a/servlet/src/digilib/servlet/ServletOps.java Sat Feb 19 12:32:20 2011 +0100 +++ b/servlet/src/digilib/servlet/ServletOps.java Sat Feb 19 22:01:12 2011 +0100 @@ -297,6 +297,7 @@ public static void sendImage(DocuImage img, String mimeType, HttpServletResponse response, Logger logger) throws ImageOpException, ServletException { + logger.debug("snding to response:"+ response + " committed=" + response.isCommitted()); if (response.isCommitted()) { logger.warn("sendImage: response already committed!"); //return; diff -r 02e1de41b6ba -r 755848b96fc1 servlet/src/digilib/util/DigilibJobCenter.java --- a/servlet/src/digilib/util/DigilibJobCenter.java Sat Feb 19 12:32:20 2011 +0100 +++ b/servlet/src/digilib/util/DigilibJobCenter.java Sat Feb 19 22:01:12 2011 +0100 @@ -51,7 +51,7 @@ } } - /** Submit job to execute + /** Submit Callable job that returns a Value to execute. * * @param job * @return Future to control the job @@ -60,6 +60,15 @@ return executor.submit(job); } + /** Submit Runnable job to execute. + * + * @param job + * @return Future to control the job + */ + public Future submit(Runnable job) { + return executor.submit(job); + } + /** Returns if the service is overloaded. * * @return