org.locomotive.loco.servlet
Class ServletPool

java.lang.Object
  |
  +--org.locomotive.util.ObjectPool
        |
        +--org.locomotive.loco.servlet.ServletPool

public class ServletPool
extends ObjectPool
implements ServletFactoryListener

Holds a pool of servlets. It's used in the ServletRoutingTable for Servlets that implement SingleThreadModel. This creates some servlets (currently, the number of minimum Threads that are created at startup), and scales to a maximum number of servlets (currently the maximum number of request Threads that are allowed by the server). This ServletPool class works in conjunction with the ServletFactory to create and maintain a pool of servlets that are ready to serve requests.


Inner classes inherited from class org.locomotive.util.ObjectPool
ObjectPool.PoolEntry
 
Fields inherited from class org.locomotive.util.ObjectPool
classname, current_open, isRunning, log, log_level, max_open, min_open, pe_in_use_hash, pe_stack, poolentry_id_sequence
 
Constructor Summary
protected ServletPool(java.lang.Class servlet_class, javax.servlet.ServletConfig servlet_config, ServletRoutingTable.ServletEntry servlet_entry)
          Creates the new ServletPool.
 
Method Summary
 java.lang.Object createNewObject()
          ServletPool does not need an implementation of this method, since the ServletFactory creates them for ServletPool and hands them over when they're ready to serve.
 void destroyObject(java.lang.Object obj)
          Calls destroy()
 int getCurrentServletCount()
          The ServletFactory calls this method when it needs to know how many servlets that the primary listener (like a ServletPool or a ServletEntry) currently holds.
 int getMaxServletCount()
          The ServletFactory calls this method when it needs to know the maximum number of servlets that the primary listener (like a ServletPool or a ServletEntry) will hold..
 int getMinServletCount()
          The ServletFactory calls this method when it needs to know how many servlets that the primary listener (like a ServletPool or a ServletEntry) needs to keep active and ready to serve.
 java.lang.Object getObject()
          Use this method to get a servlet from the ServletPool.
 ServletFactory getServletFactory()
          Returns a reference to this ServletPool's ServletFactory Object.
 javax.servlet.Servlet getServletFromPool()
          Gets a servlet from this pool.
 void handleServletFactoryEvent(ServletFactoryEvent servlet_factory_event)
          The ServletFactory calls this method when it has either successfully instantiated and initialized a servlet (and the new servlet is ready to serve requests), or when the ServletFactory needs to signal the ServletFactoryListener(s) that some other event has occurred.
 void initialize()
          This method overrides ObjectPool.initialize().
 void returnToPool(java.lang.Object obj)
          Checks to make sure that the Object you're trying to return is an instance of a Servlet, and if so this method returns that Servlet instance to the pool.
 void setMaxSize(int maxSize)
          Set the maximum size of the object pool.
 void setMinSize(int minSize)
          Set the minimum size of the ServletPool.
 void setServletFactory(ServletFactory new_servlet_factory)
           
 void wipeFromPool(java.lang.Object obj)
          This method overrides ObjectPool.wipeFromPool(Object).
 
Methods inherited from class org.locomotive.util.ObjectPool
closeCurrentPoolMembers, getLogLevel, getMaxSize, getMinSize, getNextId, getPoolSize, isRunning, log, logError, setLog, setLogLevel, startService, stopService
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ServletPool

protected ServletPool(java.lang.Class servlet_class,
                      javax.servlet.ServletConfig servlet_config,
                      ServletRoutingTable.ServletEntry servlet_entry)
               throws InitializationException
Creates the new ServletPool. Use LOCO_MIN_POOLED_THREADS for our min, and LOCO_MAX_POOLED_THREADS for our max (for now.. but this should be configurable. See the inline comments in the source code for this constructor). Logs stuff to the server log at log level 5.
Parameters:
servlet_class - the class of servlets that will populate this ServletPool.
servlet_config - the ServletConfig Object that holds any config information for the servlets to use.
Method Detail

initialize

public void initialize()
                throws InitializationException
This method overrides ObjectPool.initialize(). This needs to be called after the pool is created.

ServletPools create their own ServletFactory Thread that does the job of instantiating and initializing servlets for this pool, asynchronously, as well as waiting and retrying to instantiate and initialize more servlets if there was any temporary unavailability.

While this ServletPool's ServletFactory does its work, the ServletRoutingTable tries to get servlets from this ServletPool. If it calls ServletPool.getObject() and there aren't any servlets in the pool, getObject() returns a reference to the only instance of the UnavailableServlet. The UnavailableServlet is a multithreaded servlet that will serve the client a 503 - Service Unavailable message.
Overrides:
initialize in class ObjectPool

createNewObject

public java.lang.Object createNewObject()
                                 throws InitializationException
ServletPool does not need an implementation of this method, since the ServletFactory creates them for ServletPool and hands them over when they're ready to serve.
Overrides:
createNewObject in class ObjectPool

getObject

public java.lang.Object getObject()
Use this method to get a servlet from the ServletPool.

Under normal conditions, this method will simply get a servlet from the pool and return it right away. Regardless, this method should always return a servlet Object - though it may be the unavailable servlet.

While this ServletPool's ServletFactory does its work, the ServletRoutingTable tries to get servlets from this ServletPool. This method is called by a request Thread, and tries to get a servlet from the pool, and if there isn't one waiting in the pool it notifies the ServletFactory's Thread that it should make one. After it notifies the ServletFactory, it will wait a short period of time for the new servlet to arrive in the pool so that the request can be served correctly. Request Threads can't wait forever, so if no new servlet shows up then this method times out and returns the unavailable servlet (hopefully sending a 503 - Service Unavailable message to the client).

If this method calls ServletPool.getServletFromPool() and there aren't any servlets in the pool, getObject() eventually returns a reference to the only instance of the UnavailableServlet. The UnavailableServlet is a multithreaded servlet that will serve the client a 503 - Service Unavailable message.

Other Objects using a ServletPool should call this method to get a servlet from the pool instead of calling getServletFromPool()! This method is not synchronized, and it tries harder to return a servlet of the correct type without causing too much synchronization lock waiting. Also, getServletFromPool() does not contain any code to grow the pool up to its maximum pool size -- this method does that.

Overrides:
getObject in class ObjectPool
Returns:
a servlet Object.

getServletFromPool

public javax.servlet.Servlet getServletFromPool()
Gets a servlet from this pool.

This Object cannot simply create and return a new servlet instance, since only the ServletFactory can instantiate and initialize servlets. This is because servlet instances of this pool's type can't be created during servlet-specified downtime, so the ServletFactory Thread keeps track of when servlet instances can (and can't) be created.

Only getObject() should make calls to this method. This method is synchronized (for multithreaded use) and should only be called when necessary -- too many calls could cause lots of synchronization lock waiting, and slow down the Locomotive.

Returns:
a servlet from the pool, or the UnavailableServlet if there were no servlets waiting in the pool.

wipeFromPool

public void wipeFromPool(java.lang.Object obj)
This method overrides ObjectPool.wipeFromPool(Object). When a ServletPool wipes a servlet from the pool, it must notify its ServletFactory that it might need to make another servlet. This method removes the specified Object from the pool. Usually used if an Object has been put into some bad state.

Overrides:
wipeFromPool in class ObjectPool
Parameters:
obj - the Object to remove from the pool.

destroyObject

public void destroyObject(java.lang.Object obj)
Calls destroy()
Overrides:
destroyObject in class ObjectPool

returnToPool

public void returnToPool(java.lang.Object obj)
Checks to make sure that the Object you're trying to return is an instance of a Servlet, and if so this method returns that Servlet instance to the pool.
Overrides:
returnToPool in class ObjectPool

setMinSize

public void setMinSize(int minSize)
Set the minimum size of the ServletPool. This method overrides the method ObjectPool.setMinSize(). This implementation also notifies the ServletFactory of the change (if there is one).

Overrides:
setMinSize in class ObjectPool
Parameters:
minSize - The minimum size of the object pool.

setMaxSize

public void setMaxSize(int maxSize)
Set the maximum size of the object pool. This method overrides the method ObjectPool.setMaxSize(). This implementation also notifies the ServletFactory of the change (if there is one).

Overrides:
setMaxSize in class ObjectPool
Parameters:
maxSize - The maximum size of the object pool.

getServletFactory

public ServletFactory getServletFactory()
Returns a reference to this ServletPool's ServletFactory Object. If one doesn't already exist, a new one is instantiated, and a reference to it is returned.

Returns:
a reference to this ServletPool's ServletFactory.

setServletFactory

public void setServletFactory(ServletFactory new_servlet_factory)

getMinServletCount

public int getMinServletCount()
The ServletFactory calls this method when it needs to know how many servlets that the primary listener (like a ServletPool or a ServletEntry) needs to keep active and ready to serve.
Specified by:
getMinServletCount in interface ServletFactoryListener

getMaxServletCount

public int getMaxServletCount()
The ServletFactory calls this method when it needs to know the maximum number of servlets that the primary listener (like a ServletPool or a ServletEntry) will hold.. If the listener has all the servlets it needs, then the ServletFactory doesn't need to make any more unless the primary listener asks for more.
Specified by:
getMaxServletCount in interface ServletFactoryListener

getCurrentServletCount

public int getCurrentServletCount()
The ServletFactory calls this method when it needs to know how many servlets that the primary listener (like a ServletPool or a ServletEntry) currently holds.
Specified by:
getCurrentServletCount in interface ServletFactoryListener

handleServletFactoryEvent

public void handleServletFactoryEvent(ServletFactoryEvent servlet_factory_event)
The ServletFactory calls this method when it has either successfully instantiated and initialized a servlet (and the new servlet is ready to serve requests), or when the ServletFactory needs to signal the ServletFactoryListener(s) that some other event has occurred. In the case that a new servlet instance is ready, the new servlet is encapsulated inside the ServletFactoryEvent that is passed to this method. It is up to the ServletFactoryListener to make the servlet available to clients.

Specified by:
handleServletFactoryEvent in interface ServletFactoryListener
Parameters:
servlet_factory_event - an event that tells this ServletFactoryListener Object that a servlet is ready to serve requests (in which case the servlet is encapsulated in the event Object), or that the servlet is unavailable.
See Also:
ServletFactoryEvent