Mercurial > hg > digilib-old
changeset 544:5ff500d6812a digilibPDF
more steps towards more standard java.util.concurrent design
author | robcast |
---|---|
date | Thu, 14 Oct 2010 20:47:31 +0200 |
parents | 919e008ab1fb |
children | 88ec23c2b2fb |
files | client/digitallibrary/server/dlConfig.jsp servlet/src/digilib/image/ImageLoaderDocuImage.java servlet/src/digilib/servlet/DigilibConfiguration.java servlet/src/digilib/servlet/DigilibJobCenter.java servlet/src/digilib/servlet/Initialiser.java servlet/src/digilib/servlet/Scaler.java servlet/src/digilib/servlet/ServletOps.java |
diffstat | 7 files changed, 397 insertions(+), 355 deletions(-) [+] |
line wrap: on
line diff
--- a/client/digitallibrary/server/dlConfig.jsp Thu Oct 14 14:24:33 2010 +0200 +++ b/client/digitallibrary/server/dlConfig.jsp Thu Oct 14 20:47:31 2010 +0200 @@ -1,3 +1,4 @@ +<%@page import="digilib.servlet.DigilibJobCenter"%> <%@ page language="java" %> <%! @@ -26,6 +27,9 @@ dlRequest.setValue("pt", docBean.getNumPages(dlRequest)); // dir cache digilib.io.DocuDirCache dirCache = (digilib.io.DocuDirCache) dlConfig.getValue("servlet.dir.cache"); +// image JobCenter +DigilibJobCenter imageProcessor = (DigilibJobCenter)dlConfig.getValue("servlet.worker.imageexecutor"); + %> <html> @@ -70,11 +74,11 @@ <table> <tr> - <td>currently waiting</td><td><b><%= digilib.servlet.DigilibWorker.getNumWaiting() %></b></td> + <td>currently waiting</td><td><b><%= imageProcessor.getWaitingJobs() %></b></td> <td></td> </tr> <tr> - <td>currently running</td><td><b><%= digilib.servlet.DigilibWorker.getNumRunning() %></b></td> + <td>currently running</td><td><b><%= imageProcessor.getRunningJobs() %></b></td> <td></td> </tr> </table>
--- a/servlet/src/digilib/image/ImageLoaderDocuImage.java Thu Oct 14 14:24:33 2010 +0200 +++ b/servlet/src/digilib/image/ImageLoaderDocuImage.java Thu Oct 14 20:47:31 2010 +0200 @@ -176,9 +176,6 @@ logger.debug("loadImage " + f.getFile()); try { img = ImageIO.read(f.getFile()); - if (img == null) { - throw new FileOpException("Unable to load File!"); - } mimeType = f.getMimetype(); } catch (IOException e) { throw new FileOpException("Error reading image."); @@ -223,7 +220,6 @@ public void loadSubimage(ImageFile f, Rectangle region, int prescale) throws FileOpException { logger.debug("loadSubimage"); - // System.gc(); try { if ((reader == null) || (imgFile != f.getFile())) { getReader(f); @@ -242,9 +238,6 @@ } catch (IOException e) { throw new FileOpException("Unable to load File!"); } - if (img == null) { - throw new FileOpException("Unable to load File!"); - } } /* write image of type mt to Stream */ @@ -346,7 +339,6 @@ logger.debug("SCALE: " + scale + " ->" + scaledImg.getWidth() + "x" + scaledImg.getHeight()); img = scaledImg; - scaledImg = null; } public void blur(int radius) throws ImageOpException { @@ -373,9 +365,6 @@ .getType()); } blurredImg = blurOp.filter(img, blurredImg); - if (blurredImg == null) { - throw new ImageOpException("Unable to scale"); - } img = blurredImg; } @@ -501,9 +490,6 @@ BufferedImage rotImg = rotOp.filter(img, null); // calculate new bounding box // Rectangle2D bounds = rotOp.getBounds2D(img); - if (rotImg == null) { - throw new ImageOpException("Unable to rotate"); - } img = rotImg; // crop new image (with self-made rounding) /* @@ -538,9 +524,6 @@ AffineTransformOp mirOp = new AffineTransformOp(new AffineTransform(mx, 0, 0, my, tx, ty), renderHint); BufferedImage mirImg = mirOp.filter(img, null); - if (mirImg == null) { - throw new ImageOpException("Unable to mirror"); - } img = mirImg; }
--- a/servlet/src/digilib/servlet/DigilibConfiguration.java Thu Oct 14 14:24:33 2010 +0200 +++ b/servlet/src/digilib/servlet/DigilibConfiguration.java Thu Oct 14 20:47:31 2010 +0200 @@ -91,6 +91,8 @@ 's'); // AuthOps instance for authentication newParameter("servlet.auth.op", null, null, 's'); + // Executor for image operations + newParameter("servlet.worker.imageexecutor", null, null, 's'); /* * parameters that can be read from config file have a type 'f' @@ -123,8 +125,6 @@ newParameter("auth-file", new File("digilib-auth.xml"), null, 'f'); // sending image files as-is allowed newParameter("sendfile-allowed", Boolean.TRUE, null, 'f'); - // Debug level - newParameter("debug-level", new Integer(5), null, 'f'); // Type of DocuImage instance newParameter( "docuimage-class", @@ -145,12 +145,10 @@ newParameter("log-config-file", new File("log4j-config.xml"), null, 'f'); // maximum destination image size (0 means no limit) newParameter("max-image-size", new Integer(0), null, 'f'); - // use safe (but slower) directory indexing - newParameter("safe-dir-index", Boolean.FALSE, null, 'f'); // number of working threads newParameter("worker-threads", new Integer(1), null, 'f'); // max number of waiting threads - newParameter("max-waiting-threads", new Integer(0), null, 'f'); + newParameter("max-waiting-threads", new Integer(20), null, 'f'); // PDF generation temp directory newParameter("pdf-temp-dir", "pdf_temp", null, 'f'); // PDF generation cache directory
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlet/src/digilib/servlet/DigilibJobCenter.java Thu Oct 14 20:47:31 2010 +0200 @@ -0,0 +1,110 @@ +/** Wrapper around ExecutionService. + * + */ +package digilib.servlet; + +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; + +import org.apache.log4j.Logger; + +import digilib.image.DocuImage; + +/** Wrapper around ExecutionService. + * + * @author casties + * + */ +public class DigilibJobCenter { + /** general logger for this class */ + private static Logger logger = Logger.getLogger("digilib.jobcenter"); + /** ExecutorService */ + private ExecutorService executor; + /** max number of running threads */ + private int maxThreads = 1; + /** max number of waiting threads */ + private int maxQueueLen = 50; + + /** + * @param maxThreads + * @param maxQueueLength + */ + public DigilibJobCenter(int maxThreads, int maxQueueLen, boolean prestart) { + super(); + this.maxThreads = maxThreads; + this.maxQueueLen = maxQueueLen; + executor = Executors.newFixedThreadPool(maxThreads); + if (prestart) { + // prestart threads so Tomcat's leak protection doesn't complain + int st = ((ThreadPoolExecutor)executor).prestartAllCoreThreads(); + logger.debug("prestarting threads: "+st); + } + } + + /** Submit job to execute + * + * @param job + * @return Future to control the job + */ + public Future<DocuImage> submit(Callable<DocuImage> job) { + return executor.submit(job); + } + + /** Returns if the service is not overloaded. + * + * @return + */ + public boolean canRun() { + int jql = getWaitingJobs(); + int jrl = getRunningJobs(); + logger.debug("canRun: waiting jobs="+jql+" running jobs="+jrl); + return (jql <= maxQueueLen); + } + + /** Returns if the service is overloaded. + * + * @return + */ + public boolean isBusy() { + int jql = getWaitingJobs(); + int jrl = getRunningJobs(); + logger.debug("isBusy: waiting jobs="+jql+" running jobs="+jrl); + return (jql > maxQueueLen); + } + + public int getRunningJobs() { + return ((ThreadPoolExecutor)executor).getActiveCount(); + } + + public int getWaitingJobs() { + BlockingQueue<Runnable> jq = ((ThreadPoolExecutor)executor).getQueue(); + int jql = jq.size(); + return jql; + } + + public void setMaxThreads(int maxThreads) { + this.maxThreads = maxThreads; + } + + public int getMaxThreads() { + return maxThreads; + } + + public void setMaxQueueLen(int maxQueueLen) { + this.maxQueueLen = maxQueueLen; + } + + public int getMaxQueueLen() { + return maxQueueLen; + } + + public List<Runnable> shutdownNow() { + return executor.shutdownNow(); + } + +}
--- a/servlet/src/digilib/servlet/Initialiser.java Thu Oct 14 14:24:33 2010 +0200 +++ b/servlet/src/digilib/servlet/Initialiser.java Thu Oct 14 20:47:31 2010 +0200 @@ -21,8 +21,7 @@ package digilib.servlet; import java.io.File; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.List; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; @@ -41,33 +40,28 @@ import digilib.io.FileOps; /** - * Initalisation servlet for setup tasks. + * Singleton initalisation servlet for setup tasks and resources. * * @author casties * */ public class Initialiser extends HttpServlet { - private static final long serialVersionUID = -5126621114382549343L; - /** servlet version */ - public static final String iniVersion = "0.1b2"; + public static final String iniVersion = "0.2"; /** gengeral logger for this class */ private static Logger logger = Logger.getLogger("digilib.init"); - /** AuthOps instance */ - AuthOps authOp; - /** DocuDirCache instance */ DocuDirCache dirCache; /** DigilibConfiguration instance */ DigilibConfiguration dlConfig; - /** use authorization database */ - boolean useAuthentication = false; - + /** Executor for image jobs */ + DigilibJobCenter imageEx; + /** * Initialisation on first run. * @@ -83,8 +77,7 @@ // get our ServletContext ServletContext context = config.getServletContext(); // see if there is a Configuration instance - dlConfig = (DigilibConfiguration) context - .getAttribute("digilib.servlet.configuration"); + dlConfig = (DigilibConfiguration) context.getAttribute("digilib.servlet.configuration"); if (dlConfig == null) { // create new Configuration try { @@ -126,7 +119,7 @@ // XML version File authConf = ServletOps.getConfigFile((File) dlConfig .getValue("auth-file"), config); - authOp = new XMLAuthOps(authConf); + AuthOps authOp = new XMLAuthOps(authConf); dlConfig.setValue("servlet.auth.op", authOp); dlConfig.setValue("auth-file", authConf); } @@ -136,11 +129,9 @@ ImageOps.setDocuImage(di); // worker threads int nt = dlConfig.getAsInt("worker-threads"); - //DigilibWorker1.setSemaphore(nt, true); - ExecutorService imageEx = Executors.newFixedThreadPool(nt); + int mt = dlConfig.getAsInt("max-waiting-threads"); + imageEx = new DigilibJobCenter(nt, mt, true); dlConfig.setValue("servlet.worker.imageexecutor", imageEx); - int mt = dlConfig.getAsInt("max-waiting-threads"); - //DigilibWorker1.setMaxWaitingThreads(mt); // set as the servlets main config context.setAttribute("digilib.servlet.configuration", dlConfig); @@ -152,14 +143,28 @@ logger .info("***** Digital Image Library Initialisation Servlet (version " + iniVersion + ") *****"); - logger.warn("Already initialised?"); - // set our AuthOps - useAuthentication = dlConfig.getAsBoolean("use-authorization"); - // AuthOps instance - authOp = (AuthOps) dlConfig.getValue("servlet.auth.op"); - // DocuDirCache instance - dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); + logger.warn("Already initialised!"); } } + /** clean up local resources + * @see javax.servlet.GenericServlet#destroy() + */ + @Override + public void destroy() { + if (dirCache != null) { + // shut down dirCache? + dirCache = null; + } + if (imageEx != null) { + // shut down image thread pool + List<Runnable> rj = imageEx.shutdownNow(); + int nrj = rj.size(); + if (nrj > 0) { + logger.error("Still running threads when shutting down image job queue: "+nrj); + } + } + super.destroy(); + } + }
--- a/servlet/src/digilib/servlet/Scaler.java Thu Oct 14 14:24:33 2010 +0200 +++ b/servlet/src/digilib/servlet/Scaler.java Thu Oct 14 20:47:31 2010 +0200 @@ -2,10 +2,8 @@ import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.util.List; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import javax.servlet.ServletConfig; @@ -21,327 +19,268 @@ import digilib.io.DocuDirCache; import digilib.io.DocuDirectory; import digilib.io.DocuDirent; -import digilib.io.FileOpException; import digilib.io.FileOps; import digilib.io.ImageFile; - // TODO digilibError is not used anymore and may need to get reintegrated public class Scaler extends RequestHandler { - /** digilib servlet version (for all components) */ - public static final String dlVersion = "1.8.1a"; + /** digilib servlet version (for all components) */ + public static final String dlVersion = "1.8.1a"; - /** general error code */ - public static final int ERROR_UNKNOWN = 0; + /** general error code */ + public static final int ERROR_UNKNOWN = 0; - /** error code for authentication error */ - public static final int ERROR_AUTH = 1; + /** error code for authentication error */ + public static final int ERROR_AUTH = 1; - /** error code for file operation error */ - public static final int ERROR_FILE = 2; + /** error code for file operation error */ + public static final int ERROR_FILE = 2; - /** error code for image operation error */ - public static final int ERROR_IMAGE = 3; + /** error code for image operation error */ + public static final int ERROR_IMAGE = 3; - /** DocuDirCache instance */ - DocuDirCache dirCache; + /** DocuDirCache instance */ + DocuDirCache dirCache; /** Image executor */ - ExecutorService imageJobCenter; + DigilibJobCenter imageJobCenter; - /** authentication error image file */ - File denyImgFile; + /** authentication error image file */ + File denyImgFile; - /** image error image file */ - File errorImgFile; + /** image error image file */ + File errorImgFile; - /** not found error image file */ - File notfoundImgFile; - - /** subsampling before scaling */ - float minSubsample = 2f; + /** not found error image file */ + File notfoundImgFile; - /** send files as is? */ - boolean sendFileAllowed = true; + /** send files as is? */ + boolean sendFileAllowed = true; - /** default scaling quality */ - int defaultQuality = 1; - - /** DigilibConfiguration instance */ - DigilibConfiguration dlConfig; + /** DigilibConfiguration instance */ + DigilibConfiguration dlConfig; - /** use authorization database */ - boolean useAuthorization = true; + /** use authorization database */ + boolean useAuthorization = true; - /** AuthOps instance */ - AuthOps authOp; + /** AuthOps instance */ + AuthOps authOp; - // EXPRIMENTAL - /** try to enlarge cropping area for "oblique" angles */ - boolean wholeRotArea = false; + // EXPRIMENTAL + /** try to enlarge cropping area for "oblique" angles */ + boolean wholeRotArea = false; - - protected long getLastModified(HttpServletRequest request) { - accountlog.debug("GetLastModified from " + request.getRemoteAddr() - + " for " + request.getQueryString()); - long mtime = -1; - // create new request with defaults - DigilibRequest dlReq = new DigilibRequest(); - // set with request parameters - dlReq.setWithRequest(request); - // find the requested file - DocuDirent f = findFile(dlReq); - if (f != null) { - DocuDirectory dd = (DocuDirectory) f.getParent(); - mtime = dd.getDirMTime() / 1000 * 1000; - } - return mtime; - } - - /** - * Returns the DocuDirent corresponding to the DigilibRequest. - * - * @param dlRequest - * @return - */ - public DocuDirent findFile(DigilibRequest dlRequest) { - // find the file(set) - DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), dlRequest - .getAsInt("pn"), FileOps.CLASS_IMAGE); - return f; - } - - - - /** - * Initialisation on first run. - * @throws ServletException - * - * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) - */ - public void init(ServletConfig config) throws ServletException { - super.init(config); + protected long getLastModified(HttpServletRequest request) { + accountlog.debug("GetLastModified from " + request.getRemoteAddr() + + " for " + request.getQueryString()); + long mtime = -1; + // create new request with defaults + DigilibRequest dlReq = new DigilibRequest(); + // set with request parameters + dlReq.setWithRequest(request); + // find the requested file + DocuDirent f = findFile(dlReq); + if (f != null) { + DocuDirectory dd = (DocuDirectory) f.getParent(); + mtime = dd.getDirMTime() / 1000 * 1000; + } + return mtime; + } - System.out - .println("***** Digital Image Library Image Scaler Servlet (version " - + dlVersion + ") *****"); - // say hello in the log file - logger - .info("***** Digital Image Library Image Scaler Servlet (version " - + dlVersion + ") *****"); + /** + * Returns the DocuDirent corresponding to the DigilibRequest. + * + * @param dlRequest + * @return + */ + public DocuDirent findFile(DigilibRequest dlRequest) { + // find the file(set) + DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), + dlRequest.getAsInt("pn"), FileOps.CLASS_IMAGE); + return f; + } - // get our ServletContext - ServletContext context = config.getServletContext(); - // see if there is a Configuration instance - dlConfig = (DigilibConfiguration) context - .getAttribute("digilib.servlet.configuration"); - if (dlConfig == null) { - // no Configuration - throw new ServletException("No Configuration!"); - } - // set our AuthOps - useAuthorization = dlConfig.getAsBoolean("use-authorization"); - authOp = (AuthOps) dlConfig.getValue("servlet.auth.op"); + /** + * Initialisation on first run. + * + * @throws ServletException + * + * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) + */ + public void init(ServletConfig config) throws ServletException { + super.init(config); - // DocuDirCache instance - dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); - - // Executor - imageJobCenter = (ExecutorService) dlConfig.get("servlet.worker.imageexecutor"); - - denyImgFile = ServletOps.getFile((File) dlConfig.getValue("denied-image"), config); - errorImgFile = ServletOps.getFile((File) dlConfig.getValue("error-image"), config); - notfoundImgFile = ServletOps.getFile((File) dlConfig.getValue("notfound-image"), config); - sendFileAllowed = dlConfig.getAsBoolean("sendfile-allowed"); - minSubsample = dlConfig.getAsFloat("subsample-minimum"); - defaultQuality = dlConfig.getAsInt("default-quality"); - } + System.out + .println("***** Digital Image Library Image Scaler Servlet (version " + + dlVersion + ") *****"); + // say hello in the log file + logger.info("***** Digital Image Library Image Scaler Servlet (version " + + dlVersion + ") *****"); - - - - @Override - public void processRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, ImageOpException { + // get our ServletContext + ServletContext context = config.getServletContext(); + // see if there is a Configuration instance + dlConfig = (DigilibConfiguration) context + .getAttribute("digilib.servlet.configuration"); + if (dlConfig == null) { + // no Configuration + throw new ServletException("No Configuration!"); + } + // set our AuthOps + useAuthorization = dlConfig.getAsBoolean("use-authorization"); + authOp = (AuthOps) dlConfig.getValue("servlet.auth.op"); - - if (dlConfig == null) { - throw new ServletException("ERROR: No Configuration!"); - } - - accountlog.debug("request: " + request.getQueryString()); - logger.debug("request: " + request.getQueryString()); - + // DocuDirCache instance + dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); + + // Executor + imageJobCenter = (DigilibJobCenter) dlConfig + .getValue("servlet.worker.imageexecutor"); - // define the job information - ImageJobInformation jobdeclaration = new ImageJobInformation(dlConfig); - jobdeclaration.setWithRequest(request); - - ImageFile fileToLoad = null; - try { - fileToLoad = jobdeclaration.get_fileToLoad(); - } catch (IOException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - return; - } - - - // if requested, send image as a file - if(sendFileAllowed && jobdeclaration.checkSendAsFile()){ - String mt = null; - if (jobdeclaration.hasOption("mo", "rawfile")) { - mt = "application/octet-stream"; - } - logger.debug("Sending RAW File as is."); - try { - ServletOps.sendFile(fileToLoad.getFile(), mt, response); - } catch (FileOpException e) { - e.printStackTrace(); - } + denyImgFile = ServletOps.getFile( + (File) dlConfig.getValue("denied-image"), config); + errorImgFile = ServletOps.getFile( + (File) dlConfig.getValue("error-image"), config); + notfoundImgFile = ServletOps.getFile( + (File) dlConfig.getValue("notfound-image"), config); + sendFileAllowed = dlConfig.getAsBoolean("sendfile-allowed"); + } - return; - } + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, + ImageOpException { - - - // if possible, send the image without actually having to transform it - if(jobdeclaration.noTransformRequired()){ - logger.debug("Sending File as is."); + if (dlConfig == null) { + throw new ServletException("ERROR: No Configuration!"); + } - try { - ServletOps.sendFile(fileToLoad.getFile(), null, response); - } catch (FileOpException e) { - e.printStackTrace(); - } + accountlog.debug("request: " + request.getQueryString()); + logger.debug("request: " + request.getQueryString()); + long startTime = System.currentTimeMillis(); + + // define the job information + ImageJobInformation jobdeclaration = new ImageJobInformation(dlConfig); + jobdeclaration.setWithRequest(request); - //logger.info("Done in " - // + (System.currentTimeMillis() - startTime) + "ms"); - return; - } - + // DigilibWorker1 job=null; + ImageWorker job = null; + try { + + ImageFile fileToLoad = jobdeclaration.get_fileToLoad(); - - - if (! DigilibWorker1.canRun()) { - logger.error("Servlet overloaded!"); - try { - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); - } catch (IOException e) { - e.printStackTrace(); - } - return; - } - - - //DigilibWorker1 job=null; - ImageWorker job = null; - try { - - long startTime = System.currentTimeMillis(); + /* check permissions */ + if (useAuthorization) { + // get a list of required roles (empty if no restrictions) + List<String> rolesRequired = authOp.rolesForPath( + jobdeclaration.getFilePath(), request); + if (rolesRequired != null) { + authlog.debug("Role required: " + rolesRequired); + authlog.debug("User: " + request.getRemoteUser()); + // is the current request/user authorized? + if (!authOp.isRoleAuthorized(rolesRequired, request)) { + // send deny answer and abort + throw new AuthOpException(); + } + } + } - OutputStream outputstream = null; - outputstream = response.getOutputStream(); - - /* check permissions */ - if (useAuthorization) { - // get a list of required roles (empty if no restrictions) - List<String> rolesRequired; - try { - rolesRequired = authOp.rolesForPath(jobdeclaration.getFilePath(), request); - if (rolesRequired != null) { - authlog.debug("Role required: " + rolesRequired); - authlog.debug("User: " + request.getRemoteUser()); - // is the current request/user authorized? - if (!authOp.isRoleAuthorized(rolesRequired, request)) { - // send deny answer and abort - throw new AuthOpException(); - } - } + // if requested, send image as a file + if (sendFileAllowed && jobdeclaration.checkSendAsFile()) { + String mt = null; + if (jobdeclaration.hasOption("mo", "rawfile")) { + mt = "application/octet-stream"; + } + logger.debug("Sending RAW File as is."); + logger.info("Done in " + (System.currentTimeMillis() - startTime) + "ms"); + ServletOps.sendFile(fileToLoad.getFile(), mt, response); + return; + } - } catch (AuthOpException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + // if possible, send the image without actually having to transform + // it + if (jobdeclaration.noTransformRequired()) { + logger.debug("Sending File as is."); + ServletOps.sendFile(fileToLoad.getFile(), null, response); + logger.info("Done in " + (System.currentTimeMillis() - startTime) + "ms"); + return; + } - - //job = new DigilibImageWorker1(dlConfig, outputstream , jobdeclaration); - //job.run(); - - // create job - job = new ImageWorker(dlConfig, jobdeclaration); - // submit job + // check load of workers + if (imageJobCenter.isBusy()) { + logger.error("Servlet overloaded!"); + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + return; + } + // create job + job = new ImageWorker(dlConfig, jobdeclaration); + // submit job Future<DocuImage> jobResult = imageJobCenter.submit(job); // wait for result DocuImage img = jobResult.get(); // send image - ServletOps.writeImage(img, null, outputstream); - - logger.debug("Job Processing Time: "+ (System.currentTimeMillis()-startTime) + "ms"); - - } catch (IOException e) { - e.printStackTrace(); - logger.error(e.getClass()+": "+ e.getMessage()); - //response.sendError(1); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - logger.error(e.getClass()+": "+ e.getMessage()); + ServletOps.sendImage(img, null, response); + logger.debug("Job Processing Time: " + + (System.currentTimeMillis() - startTime) + "ms"); + + } catch (IOException e) { + logger.error(e.getClass() + ": " + e.getMessage()); + // response.sendError(1); + } catch (AuthOpException e) { + logger.error(e.getClass() + ": " + e.getMessage()); + // response.sendError(1); + } catch (InterruptedException e) { + logger.error(e.getClass() + ": " + e.getMessage()); } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - logger.error(e.getClass()+": "+ e.getMessage()); - logger.error("caused by: "+ e.getCause().getMessage()); + logger.error(e.getClass() + ": " + e.getMessage()); + logger.error("caused by: " + e.getCause().getMessage()); } - } - - - /** - * Sends an error to the client as text or image. - * - * @param asHTML - * @param type - * @param msg - * @param response - */ - public void digilibError(boolean asHTML, int type, String msg, - HttpServletResponse response) { - try { - File img = null; - if (type == ERROR_AUTH) { - if (msg == null) { - msg = "ERROR: Unauthorized access!"; - } - img = denyImgFile; - } else if (type == ERROR_FILE) { - if (msg == null) { - msg = "ERROR: Image file not found!"; - } - img = notfoundImgFile; - } else { - if (msg == null) { - msg = "ERROR: Other image error!"; - } - img = this.errorImgFile; - } - if (asHTML && (img != null)) { - ServletOps.htmlMessage(msg, response); - } else { - ServletOps.sendFile(img, null, response); - } - } catch (IOException e) { - logger.error("Error sending error!", e); - } + } - } + /** + * Sends an error to the client as text or image. + * + * @param asHTML + * @param type + * @param msg + * @param response + */ + public void digilibError(boolean asHTML, int type, String msg, + HttpServletResponse response) { + try { + File img = null; + if (type == ERROR_AUTH) { + if (msg == null) { + msg = "ERROR: Unauthorized access!"; + } + img = denyImgFile; + } else if (type == ERROR_FILE) { + if (msg == null) { + msg = "ERROR: Image file not found!"; + } + img = notfoundImgFile; + } else { + if (msg == null) { + msg = "ERROR: Other image error!"; + } + img = this.errorImgFile; + } + if (asHTML && (img != null)) { + ServletOps.htmlMessage(msg, response); + } else { + ServletOps.sendFile(img, null, response); + } + } catch (IOException e) { + logger.error("Error sending error!", e); + } - public static String getVersion(){ - return dlVersion; - } - + } + + public static String getVersion() { + return dlVersion; + } }
--- a/servlet/src/digilib/servlet/ServletOps.java Thu Oct 14 14:24:33 2010 +0200 +++ b/servlet/src/digilib/servlet/ServletOps.java Thu Oct 14 20:47:31 2010 +0200 @@ -34,7 +34,6 @@ import org.apache.log4j.Logger; import digilib.image.DocuImage; -import digilib.image.ImageOps; import digilib.io.FileOpException; import digilib.io.FileOps; @@ -189,9 +188,10 @@ * ServletResponse where the image file will be sent. * @throws FileOpException * Exception is thrown for a IOException. + * @throws IOException */ public static void sendFile(File f, String mt, HttpServletResponse response) - throws FileOpException { + throws FileOpException, IOException { logger.debug("sendRawFile(" + mt + ", " + f + ")"); if (mt == null) { // auto-detect mime-type @@ -202,37 +202,42 @@ } response.setContentType(mt); // open file - try { - if (mt.equals("application/octet-stream")) { - response.addHeader("Content-Disposition", - "attachment; filename=\"" + f.getName() + "\""); - } - FileInputStream inFile = new FileInputStream(f); - OutputStream outStream = response.getOutputStream(); - byte dataBuffer[] = new byte[4096]; - int len; - while ((len = inFile.read(dataBuffer)) != -1) { - // copy out file - outStream.write(dataBuffer, 0, len); - } - inFile.close(); - response.flushBuffer(); - } catch (IOException e) { - throw new FileOpException("Unable to send file."); + if (mt.equals("application/octet-stream")) { + response.addHeader("Content-Disposition", "attachment; filename=\"" + + f.getName() + "\""); } + FileInputStream inFile = new FileInputStream(f); + OutputStream outStream = response.getOutputStream(); + byte dataBuffer[] = new byte[4096]; + int len; + while ((len = inFile.read(dataBuffer)) != -1) { + // copy out file + outStream.write(dataBuffer, 0, len); + outStream.flush(); + } + inFile.close(); + response.flushBuffer(); } - public static void writeImage(DocuImage img, String mimeType, OutputStream outstream) throws FileOpException, - IOException { - /* write the resulting image */ - + /** + * Write image img to ServletResponse response. + * + * @param img + * @param mimeType + * @param response + * @throws FileOpException + * @throws IOException + */ + public static void sendImage(DocuImage img, String mimeType, + HttpServletResponse response) throws FileOpException, IOException { + OutputStream outstream = response.getOutputStream(); // setup output -- if mime type is set use that otherwise // if source is JPG then dest will be JPG else it's PNG if (mimeType == null) { mimeType = img.getMimetype(); } - if ((mimeType.equals("image/jpeg") - || mimeType.equals("image/jp2") || mimeType.equals("image/fpx"))) { + if ((mimeType.equals("image/jpeg") || mimeType.equals("image/jp2") || mimeType + .equals("image/fpx"))) { mimeType = "image/jpeg"; } else { mimeType = "image/png"; @@ -241,8 +246,6 @@ // write the image img.writeImage(mimeType, outstream); outstream.flush(); - - logger.debug("write image done"); img.dispose(); }