changeset 291:1cec876f2788 gen2

servlet version 2b1 ("scaleable digilib") - only using Semaphore to limit max number of threads
author robcast
date Thu, 21 Oct 2004 22:00:55 +0200
parents 5d0c0da080ec
children 886d6cee935c
files servlet/src/digilib/servlet/DigilibConfiguration.java servlet/src/digilib/servlet/DigilibJob.java servlet/src/digilib/servlet/DigilibManager.java servlet/src/digilib/servlet/DigilibSender.java servlet/src/digilib/servlet/DigilibWorker.java servlet/src/digilib/servlet/Initialiser.java servlet/src/digilib/servlet/Scaler.java servlet/src/digilib/servlet/ServletOps.java servlet/src/digilib/servlet/Texter.java
diffstat 9 files changed, 78 insertions(+), 360 deletions(-) [+]
line wrap: on
line diff
--- a/servlet/src/digilib/servlet/DigilibConfiguration.java	Thu Oct 21 20:53:37 2004 +0200
+++ b/servlet/src/digilib/servlet/DigilibConfiguration.java	Thu Oct 21 22:00:55 2004 +0200
@@ -91,9 +91,6 @@
 			's');
 		// AuthOps instance for authentication
 		newParameter("servlet.auth.op", null, null, 's');
-		// worker queues
-		newParameter("servlet.fast.queue", null, null, 's');
-		newParameter("servlet.slow.queue", null, null, 's');
 
 		/*
 		 * parameters that can be read from config file have a type 'f'
@@ -144,14 +141,8 @@
 		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 fast worker threads
-		newParameter("worker-fast-lanes", new Integer(2), null, 'f');
-		// length of fast worker queue
-		newParameter("worker-fast-queue", new Integer(100), null, 'f');
-		// number of slow worker threads
-		newParameter("worker-slow-lanes", new Integer(2), null, 'f');
-		// length of slow worker queue
-		newParameter("worker-slow-queue", new Integer(100), null, 'f');
+		// number of working threads
+		newParameter("worker-threads", new Integer(1), null, 'f');
 
 	}
 
--- a/servlet/src/digilib/servlet/DigilibJob.java	Thu Oct 21 20:53:37 2004 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/* DigilibJob.java -- digilib job for worker
- * 
- * Digital Image Library servlet components
- * 
- * Copyright (C) 2004 Robert Casties (robcast@mail.berlios.de)
- * 
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- * 
- * Please read license.txt for the full details. A copy of the GPL may be found
- * at http://www.gnu.org/copyleft/lgpl.html
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- *  
- * Created on 18.10.2004
- */
-package digilib.servlet;
-
-import digilib.image.DocuImage;
-
-/** digilib job for worker.
- * 
- * @author casties
- *
- */
-public class DigilibJob {
-
-	private DigilibConfiguration config;
-	
-	private DigilibRequest request;
-	
-	private DocuImage image;
-	
-	
-	/**
-	 * @return Returns the config.
-	 */
-	public DigilibConfiguration getConfig() {
-		return config;
-	}
-	/**
-	 * @param config The config to set.
-	 */
-	public void setConfig(DigilibConfiguration config) {
-		this.config = config;
-	}
-	/**
-	 * @return Returns the image.
-	 */
-	public DocuImage getImage() {
-		return image;
-	}
-	/**
-	 * @param image The image to set.
-	 */
-	public void setImage(DocuImage image) {
-		this.image = image;
-	}
-	/**
-	 * @return Returns the request.
-	 */
-	public DigilibRequest getRequest() {
-		return request;
-	}
-	/**
-	 * @param request The request to set.
-	 */
-	public void setRequest(DigilibRequest request) {
-		this.request = request;
-	}
-}
--- a/servlet/src/digilib/servlet/DigilibManager.java	Thu Oct 21 20:53:37 2004 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/* DigilibManager.java -- work queue manager
- * 
- * Digital Image Library servlet components
- * 
- * Copyright (C) 2004 Robert Casties (robcast@mail.berlios.de)
- * 
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- * 
- * Please read license.txt for the full details. A copy of the GPL may be found
- * at http://www.gnu.org/copyleft/lgpl.html
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- *  
- * Created on 18.10.2004
- */
-
-package digilib.servlet;
-
-import EDU.oswego.cs.dl.util.concurrent.BoundedBuffer;
-import EDU.oswego.cs.dl.util.concurrent.Executor;
-import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
-
-/** work queue manager.
- * 
- * @author casties
- *
- */
-public class DigilibManager implements Executor {
-	
-	private PooledExecutor workerQueue = null;
-	
-	private BoundedBuffer jobQueue = null;
-	
-	/**
-	 * @param numFastLanes
-	 * @param numSlowLanes
-	 */
-	public DigilibManager(int numLanes, int queueMax) {
-		super();
-		
-		// create job queue
-		jobQueue = new BoundedBuffer(queueMax);
-		// create work queue
-		workerQueue = new PooledExecutor(jobQueue, numLanes);
-		workerQueue.abortWhenBlocked();
-
-	}
-	
-	
-	public void execute(Runnable worker) throws InterruptedException {
-		workerQueue.execute(worker);
-	}
-	
-	public int getQueueSize() {
-		return jobQueue.size();
-	}
-}
--- a/servlet/src/digilib/servlet/DigilibSender.java	Thu Oct 21 20:53:37 2004 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/* DigilibSender.java -- image file send worker
- * 
- * Digital Image Library servlet components
- * 
- * Copyright (C) 2004 Robert Casties (robcast@mail.berlios.de)
- * 
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- * 
- * Please read license.txt for the full details. A copy of the GPL may be found
- * at http://www.gnu.org/copyleft/lgpl.html
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- *  
- * Created on 18.10.2004
- */
-package digilib.servlet;
-
-import java.io.File;
-
-import javax.servlet.http.HttpServletResponse;
-
-import digilib.io.FileOpException;
-
-/**
- * image file send worker.
- * 
- * @author casties
- *  
- */
-public class DigilibSender extends DigilibWorker {
-
-	private File file;
-
-	private String mimetype;
-
-	private HttpServletResponse response;
-
-	/**
-	 * @param file
-	 * @param mimetype
-	 * @param response
-	 */
-	public DigilibSender(File file, String mimetype,
-			HttpServletResponse response) {
-		super();
-		this.file = file;
-		this.mimetype = mimetype;
-		this.response = response;
-	}
-
-	/**
-	 * Actually send the file.
-	 *  
-	 */
-	public void work() {
-		logger.debug("worker " + this.getName() + " sending file:"
-				+ file.getName());
-		try {
-			//sleep(2000);
-			ServletOps.sendFileImmediately(file, mimetype, response);
-		} catch (FileOpException e) {
-			logger.error("Unable to send file " + file.getPath() + " because "
-					+ e);
-		}
-		logger.debug("worker "+this.getName()+" done");
-	}
-
-}
--- a/servlet/src/digilib/servlet/DigilibWorker.java	Thu Oct 21 20:53:37 2004 +0200
+++ b/servlet/src/digilib/servlet/DigilibWorker.java	Thu Oct 21 22:00:55 2004 +0200
@@ -25,25 +25,24 @@
 import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
 import EDU.oswego.cs.dl.util.concurrent.Semaphore;
 
-
-
-/** image operation worker.
+/**
+ * image operation worker.
  * 
  * @author casties
- *
+ *  
  */
-public abstract class DigilibWorker extends Thread {
-	
+public abstract class DigilibWorker {
+
 	protected static Logger logger = Logger.getLogger(DigilibWorker.class);
 
 	private static int runningThreads = 0;
-	
-	public static Semaphore lock = new FIFOSemaphore(4);
+
+	public static Semaphore lock = new FIFOSemaphore(1);
 
 	protected boolean busy = false;
-	
-	protected Exception error; 
-	
+
+	protected Exception error;
+
 	/**
 	 * @param job
 	 */
@@ -52,34 +51,39 @@
 		busy = true;
 		error = null;
 	}
-	
-	
+
 	public abstract void work() throws Exception;
-	
-	/** Actually do the work.
-	 * 
-	 * @see java.lang.Runnable#run()
+
+	/**
+	 * Do the work.
 	 */
 	public void run() {
 		try {
 			lock.acquire();
-		logger.debug((++runningThreads)+" running threads");
+		} catch (InterruptedException e) {
+			error = e;
+			busy = false;
+			return;
+		}
+		logger.debug((++runningThreads) + " running threads");
 		try {
 			work();
 		} catch (Exception e) {
 			error = e;
 			logger.error(e);
 		}
-		synchronized (this) {
-			busy = false;
-			this.notify();
-		}
+		busy = false;
 		runningThreads--;
 		lock.release();
-		} catch (InterruptedException e1) {
-			// TODO Auto-generated catch block
-			e1.printStackTrace();
-		}
+	}
+
+	
+	/** Returns the name of this thread.
+	 * 
+	 * @return
+	 */
+	public String getName() {
+		return Thread.currentThread().getName();
 	}
 	
 	/**
@@ -89,19 +93,34 @@
 		return busy;
 	}
 
-	/** returns if an error occurred.
+	/**
+	 * returns if an error occurred.
 	 * 
 	 * @return
 	 */
 	public boolean hasError() {
 		return (error != null);
 	}
-	
+
 	/**
 	 * @return Returns the error.
 	 */
 	public Exception getError() {
 		return error;
 	}
-	
+
+	/**
+	 * @return Returns the lock.
+	 */
+	public static Semaphore getLock() {
+		return lock;
+	}
+
+	/**
+	 * @param lock
+	 *            The lock to set.
+	 */
+	public static void setLock(Semaphore lock) {
+		DigilibWorker.lock = lock;
+	}
 }
--- a/servlet/src/digilib/servlet/Initialiser.java	Thu Oct 21 20:53:37 2004 +0200
+++ b/servlet/src/digilib/servlet/Initialiser.java	Thu Oct 21 22:00:55 2004 +0200
@@ -30,6 +30,8 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.xml.DOMConfigurator;
 
+import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
+import EDU.oswego.cs.dl.util.concurrent.Semaphore;
 import digilib.auth.AuthOps;
 import digilib.auth.XMLAuthOps;
 import digilib.io.AliasingDocuDirCache;
@@ -47,7 +49,7 @@
 	private static final long serialVersionUID = -5126621114382549343L;
 
 	/** servlet version */
-	public static final String iniVersion = "0.1a1";
+	public static final String iniVersion = "0.1b1";
 
 	/** gengeral logger for this class */
 	private static Logger logger = Logger.getLogger("digilib.init");
@@ -64,10 +66,6 @@
 	/** use authorization database */
 	boolean useAuthentication = false;
 
-	private DigilibManager fastQueue;
-
-	private DigilibManager slowQueue;
-
 	/**
 	 * Initialisation on first run.
 	 * 
@@ -135,15 +133,10 @@
 						.getAsString("docuimage-class"));
 				dlConfig.setDocuImageClass(cl);
 				dlConfig.setValue("servlet.docuimage.class", cl.getName());
-				// DigilibManager work queue
-				int fl = dlConfig.getAsInt("worker-fast-lanes");
-				int fq = dlConfig.getAsInt("worker-fast-queue");
-				fastQueue = new DigilibManager(fl, fq);
-				dlConfig.setValue("servlet.fast.queue", fastQueue);
-				int sl = dlConfig.getAsInt("worker-slow-lanes");
-				int sq = dlConfig.getAsInt("worker-slow-queue");
-				slowQueue = new DigilibManager(sl, sq);
-				dlConfig.setValue("servlet.slow.queue", slowQueue);
+				// worker threads
+				int nt = dlConfig.getAsInt("worker-threads");
+				Semaphore lck = new FIFOSemaphore(nt); 
+				DigilibWorker.setLock(lck);
 				// set as the servlets main config
 				context.setAttribute("digilib.servlet.configuration", dlConfig);
 
@@ -162,11 +155,6 @@
 			authOp = (AuthOps) dlConfig.getValue("servlet.auth.op");
 			// DocuDirCache instance
 			dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache");
-			// work queues
-			fastQueue = (DigilibManager) dlConfig
-					.getValue("servlet.fast.queue");
-			slowQueue = (DigilibManager) dlConfig
-					.getValue("servlet.slow.queue");
 		}
 	}
 
--- a/servlet/src/digilib/servlet/Scaler.java	Thu Oct 21 20:53:37 2004 +0200
+++ b/servlet/src/digilib/servlet/Scaler.java	Thu Oct 21 22:00:55 2004 +0200
@@ -59,7 +59,7 @@
 	private static final long serialVersionUID = -325080527268912852L;
 
 	/** digilib servlet version (for all components) */
-	public static final String dlVersion = "2.0a6";
+	public static final String dlVersion = "2.0b1";
 
 	/** logger for accounting requests */
 	private static Logger accountlog = Logger.getLogger("account.request");
@@ -103,12 +103,6 @@
 	/** DigilibConfiguration instance */
 	DigilibConfiguration dlConfig;
 
-	/** fast worker queue */
-	DigilibManager fastQueue;
-
-	/** slow image worker queue */
-	DigilibManager slowQueue;
-
 	/** use authorization database */
 	boolean useAuthorization = true;
 
@@ -147,9 +141,6 @@
 		// set our AuthOps
 		useAuthorization = dlConfig.getAsBoolean("use-authorization");
 		authOp = (AuthOps) dlConfig.getValue("servlet.auth.op");
-		// work queues
-		fastQueue = (DigilibManager) dlConfig.getValue("servlet.fast.queue");
-		slowQueue = (DigilibManager) dlConfig.getValue("servlet.slow.queue");
 
 		// DocuDirCache instance
 		dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache");
@@ -189,7 +180,7 @@
 	}
 
 	/** main request handler. */
-void processRequest(HttpServletRequest request, HttpServletResponse response)
+	void processRequest(HttpServletRequest request, HttpServletResponse response)
 			throws ServletException {
 
 		if (dlConfig == null) {
@@ -401,7 +392,7 @@
 					fileToLoad = fileset.getBiggest();
 				}
 			}
-			logger.info("Loading: " + fileToLoad.getFile());
+			logger.info("Planning to load: " + fileToLoad.getFile());
 
 			/*
 			 * send the image if its mo=(raw)file
@@ -414,8 +405,7 @@
 						mt = "application/octet-stream";
 					}
 					logger.debug("Sending RAW File as is.");
-					ServletOps.sendFile(fileToLoad.getFile(), mt, response,
-							fastQueue);
+					ServletOps.sendFile(fileToLoad.getFile(), mt, response);
 					logger.info("Done in "
 							+ (System.currentTimeMillis() - startTime) + "ms");
 					return;
@@ -472,8 +462,7 @@
 
 				logger.debug("Sending File as is.");
 
-				ServletOps.sendFile(fileToLoad.getFile(), null, response,
-						fastQueue);
+				ServletOps.sendFile(fileToLoad.getFile(), null, response);
 
 				logger.info("Done in "
 						+ (System.currentTimeMillis() - startTime) + "ms");
@@ -581,8 +570,10 @@
 			outerUserImgArea = outerUserImgArea.createIntersection(imgBounds);
 
 			// check image parameters sanity
-			if ((outerUserImgArea.getWidth() < 1) || (outerUserImgArea.getHeight() < 1)
-					|| (scaleXY * outerUserImgArea.getWidth() < 2) || (scaleXY * outerUserImgArea.getHeight() < 2)) {
+			if ((outerUserImgArea.getWidth() < 1)
+					|| (outerUserImgArea.getHeight() < 1)
+					|| (scaleXY * outerUserImgArea.getWidth() < 2)
+					|| (scaleXY * outerUserImgArea.getHeight() < 2)) {
 				logger.error("ERROR: invalid scale parameter set!");
 				throw new ImageOpException("Invalid scale parameter set!");
 			}
@@ -593,34 +584,14 @@
 
 			DigilibWorker job = new DigilibImageWorker(dlConfig, response,
 					mimeType, scaleQual, dlRequest, paramROT, paramCONT,
-					paramBRGT, paramRGBM, paramRGBA, fileToLoad, scaleXY, outerUserImgArea,
-					innerUserImgArea, minSubsample, wholeRotArea);
-			
-			try {
-				// we're cheating
-				job.run();
-			} catch (Exception e1) {
-				throw new ImageOpException(e1.toString());
+					paramBRGT, paramRGBM, paramRGBA, fileToLoad, scaleXY,
+					outerUserImgArea, innerUserImgArea, minSubsample,
+					wholeRotArea);
+
+			job.run();
+			if (job.hasError()) {
+				throw new ImageOpException(job.getError().toString());
 			}
-			
-			/*
-			try {
-				slowQueue.execute(job);
-				logger.debug("servlet job submitted by "
-						+ Thread.currentThread().getName() + " ("
-						+ slowQueue.getQueueSize() + " in queue)");
-				
-				synchronized (job) {
-					while (job.isBusy()) {
-						Thread.yield();
-						job.wait();
-					}
-				}
-			} catch (InterruptedException e1) {
-				throw new ImageOpException("INTERRUPTED: " + e1.getMessage());
-			}
-			*/
-
 
 			logger.debug("servlet done in "
 					+ (System.currentTimeMillis() - startTime));
@@ -647,6 +618,7 @@
 					"ERROR: Other Image Operation Error: " + e, response);
 		}
 	}
+
 	/**
 	 * Sends an error to the client as text or image.
 	 * 
@@ -673,7 +645,7 @@
 			if (asHTML && (img != null)) {
 				ServletOps.htmlMessage(msg, response);
 			} else {
-				ServletOps.sendFile(img, null, response, fastQueue);
+				ServletOps.sendFile(img, null, response);
 			}
 		} catch (IOException e) {
 			logger.error("Error sending error!", e);
--- a/servlet/src/digilib/servlet/ServletOps.java	Thu Oct 21 20:53:37 2004 +0200
+++ b/servlet/src/digilib/servlet/ServletOps.java	Thu Oct 21 22:00:55 2004 +0200
@@ -33,7 +33,6 @@
 
 import org.apache.log4j.Logger;
 
-import EDU.oswego.cs.dl.util.concurrent.Executor;
 import digilib.io.FileOpException;
 import digilib.io.FileOps;
 
@@ -141,7 +140,7 @@
 	 * @throws FileOpException
 	 *             Exception is thrown for a IOException.
 	 */
-	public static void sendFileImmediately(File f, String mt,
+	public static void sendFile(File f, String mt,
 			HttpServletResponse response) throws FileOpException {
 		logger.debug("sendRawFile(" + mt + ", " + f + ")");
 		if (mt == null) {
@@ -173,45 +172,4 @@
 		}
 	}
 
-	/**
-	 * Transfers an image file as-is with the mime type mt using a work queue.
-	 * 
-	 * The local file is copied to the <code>OutputStream</code> of the
-	 * <code>ServletResponse</code>. If mt is null then the mime-type is
-	 * auto-detected with mimeForFile.
-	 * 
-	 * @param mt
-	 *            mime-type of the file.
-	 * @param f
-	 *            Image file to be sent.
-	 * @param res
-	 *            ServletResponse where the image file will be sent.
-	 * @throws FileOpException
-	 *             Exception is thrown for a IOException.
-	 */
-	public static void sendFile(File f, String mimetype,
-			HttpServletResponse response, Executor workQueue)
-			throws FileOpException {
-		// we're cheating
-		sendFileImmediately(f, mimetype, response);
-		/*
-		// create worker
-		DigilibSender job = new DigilibSender(f, null, response);
-		try {
-			logger.debug("queue size: "
-					+ ((DigilibManager) workQueue).getQueueSize());
-			workQueue.execute(job);
-			logger.debug("job sent!");
-			synchronized (job) {
-				while (job.isBusy()) {
-					job.wait();
-				}
-			}
-		} catch (InterruptedException e) {
-			throw new FileOpException("INTERRUPTED: Unable to send file. " + e);
-		}
-		*/
-
-	}
-
 }
\ No newline at end of file
--- a/servlet/src/digilib/servlet/Texter.java	Thu Oct 21 20:53:37 2004 +0200
+++ b/servlet/src/digilib/servlet/Texter.java	Thu Oct 21 22:00:55 2004 +0200
@@ -149,11 +149,11 @@
 			 */
 			TextFile f = getTextFile(dlRequest, "/txt");
 			if (f != null) {
-				ServletOps.sendFileImmediately(f.getFile(), null, response);
+				ServletOps.sendFile(f.getFile(), null, response);
 			} else {
 				f = getTextFile(dlRequest, "");
 				if (f != null) {
-					ServletOps.sendFileImmediately(f.getFile(),	null, response);
+					ServletOps.sendFile(f.getFile(),	null, response);
 				} else {	
 					ServletOps.htmlMessage("No Text-File!", response);
 				}