package org.jacorb.poa; /* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.jacorb.config.Configurable; import org.jacorb.config.Configuration; import org.jacorb.config.ConfigurationException; import org.jacorb.orb.dsi.ServerRequest; import org.jacorb.poa.except.ResourceLimitReachedException; import org.jacorb.poa.util.StringPair; import org.omg.CORBA.BAD_INV_ORDER; import org.slf4j.Logger; /** * This class manages a queue of ServerRequest objects. * * @author Reimo Tiedemann, FU Berlin */ public class RequestQueue implements Configurable { private RequestQueueListener queueListener; /** the configuration object for this queue */ private org.jacorb.config.Configuration configuration = null; private Logger logger; private int queueMin; private int queueMax; private boolean queueWait; private boolean configured = false; private final LinkedList<ServerRequest> queue = new LinkedList<ServerRequest>(); public synchronized void configure(Configuration myConfiguration) throws ConfigurationException { if (configured) { return; } this.configuration = (org.jacorb.config.Configuration)myConfiguration; logger = configuration.getLogger("org.jacorb.poa.queue"); queueMax = configuration.getAttributeAsInteger("jacorb.poa.queue_max", 100); queueMin = configuration.getAttributeAsInteger("jacorb.poa.queue_min", 10); queueWait = configuration.getAttributeAsBoolean("jacorb.poa.queue_wait",false); List queueListeners = configuration.getAttributeList("jacorb.poa.queue_listeners"); for (Iterator i = queueListeners.iterator(); i.hasNext();) { String className = (String)i.next(); try { RequestQueueListener rql = (RequestQueueListener) org.jacorb.util.ObjectUtil.classForName(className).newInstance(); addRequestQueueListener(rql); } catch (Exception ex) { throw new ConfigurationException ("could not instantiate queue listener", ex); } } configured = true; } /** * Adds a request to this queue. The properties * <code>jacorb.poa.queue_{min,max,wait}</code> specify what happens when * the queue is full, i.e. when it already contains <code>queue_max</code> * requests. If <code>queue_wait</code> is <i>off</i>, then this method * does not add the request and throws a * <code>ResourceLimitReachedException</code>. If <code>queue_wait</code> * is <i>on</i>, then this method blocks until no more than * <code>queue_min</code> requests are in the queue; it then adds the * request, and returns. * * @param request the request * * @throws ResourceLimitReachedException the resource limit reached * exception */ protected synchronized void add(ServerRequest request) throws ResourceLimitReachedException { checkIsConfigured(); if (queueMax > 0 && queue.size() >= queueMax ) { if (logger.isWarnEnabled()) { logger.warn("Request queue is full, consider increasing " + "jacorb.poa.queue_max (currently: " + queueMax + ")"); } if ( queueWait ) { while (queue.size() > queueMin ) { try { this.wait(); } catch (InterruptedException ex) { // ignore } } } else { throw new ResourceLimitReachedException(); } } queue.add(request); if (logger.isDebugEnabled()) { logger.debug("rid: " + request.requestId() + " opname: " + request.operation() + " is queued (queue size: " + queue.size() + ")"); } // notify a queue listener if (queueListener != null) { queueListener.requestAddedToQueue(request, queue.size()); } } /** * Adds the request queue listener. * * @param listener the listener */ protected synchronized void addRequestQueueListener(RequestQueueListener listener) { checkIsConfigured(); queueListener = EventMulticaster.add(queueListener, listener); } /** * Deliver content. * * @return the string pair[] */ protected synchronized StringPair[] deliverContent() { checkIsConfigured(); StringPair[] result = new StringPair[queue.size()]; Iterator en = queue.iterator(); ServerRequest sr; for (int i=0; i<result.length; i++) { sr = (ServerRequest) en.next(); result[i] = new StringPair(Integer.toString(sr.requestId()), new String( sr.objectId() ) ); } return result; } /** * Only used by the POA GUI. * * @param rid the rid * @return the element and remove */ synchronized ServerRequest getElementAndRemove(int rid) { checkIsConfigured(); if (!queue.isEmpty()) { Iterator en = queue.iterator(); ServerRequest result; while (en.hasNext()) { result = (ServerRequest) en.next(); if (result.requestId() == rid) { en.remove(); this.notifyAll(); // notify a queue listener if (queueListener != null) { queueListener.requestRemovedFromQueue(result, queue.size()); } return result; } } } return null; } /** * Used by the RequestController - gets the first element * * @return the first */ protected synchronized ServerRequest getFirst() { checkIsConfigured(); if (!queue.isEmpty()) { return (ServerRequest) queue.getFirst(); } return null; } /** * Used by the RequestController - checks if is empty. * * @return true, if is empty */ protected boolean isEmpty() { checkIsConfigured(); return queue.isEmpty(); } /** * Used by the RequestController - removes the first. * * @return the server request */ protected synchronized ServerRequest removeFirst() { checkIsConfigured(); if (!queue.isEmpty()) { ServerRequest result = (ServerRequest) queue.removeFirst(); this.notifyAll(); // notify a queue listener if (queueListener != null) { queueListener.requestRemovedFromQueue(result, queue.size()); } return result; } return null; } /** * Used by the RequestController - removes the last. * * @return the server request */ protected synchronized ServerRequest removeLast() { checkIsConfigured(); if (!queue.isEmpty()) { ServerRequest result = (ServerRequest) queue.removeLast(); this.notifyAll(); // notify a queue listener if (queueListener != null) { queueListener.requestRemovedFromQueue(result, queue.size()); } return result; } return null; } /** * Removes the request queue listener. * * @param listener the listener */ protected synchronized void removeRequestQueueListener(RequestQueueListener listener) { checkIsConfigured(); queueListener = EventMulticaster.remove(queueListener, listener); } /** * Size. * * @return the int */ protected int size() { return queue.size(); } /** * Check is configured. */ private void checkIsConfigured() { if (!configured) { throw new BAD_INV_ORDER("RequestQueue is not configured yet."); } } }