Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

FailFastPoolConnectionManager.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2004 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Emmanuel Cecchet.
00022  * Contributor(s): ______________________.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.connection;
00026 
00027 import java.io.Serializable;
00028 import java.sql.Connection;
00029 import java.util.EmptyStackException;
00030 
00031 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException;
00032 import org.objectweb.cjdbc.common.i18n.Translate;
00033 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00034 
00035 /**
00036  * This connection manager returns <code>null</code> when the pool is empty.
00037  * Therefore all requests fail fast until connections are freed.
00038  * 
00039  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
00040  * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
00041  * @version 1.0
00042  */
00043 public class FailFastPoolConnectionManager
00044     extends
00045       AbstractPoolConnectionManager implements Serializable
00046 {
00047 
00048   /**
00049    * Creates a new <code>FailFastPoolConnectionManager</code> instance.
00050    * 
00051    * @param backendUrl URL of the <code>DatabaseBackend</code> owning this
00052    *            connection manager
00053    * @param backendName name of the <code>DatabaseBackend</code> owning this
00054    *            connection manager
00055    * @param login backend connection login to be used by this connection
00056    *            manager
00057    * @param password backend connection password to be used by this connection
00058    *            manager
00059    * @param driverPath path for driver
00060    * @param driverClassName class name for driver
00061    * @param poolSize size of the connection pool
00062    */
00063   public FailFastPoolConnectionManager(String backendUrl, String backendName,
00064       String login, String password, String driverPath, String driverClassName,
00065       int poolSize)
00066   {
00067     super(backendUrl, backendName, login, password, driverPath,
00068         driverClassName, poolSize);
00069   }
00070 
00071   /**
00072    * Gets a connection from the pool. Returns <code>null</code> if the pool
00073    * is empty.
00074    * 
00075    * @return a connection from the pool or <code>null</code> if the pool is
00076    *         exhausted
00077    * @throws UnreachableBackendException if the backend must be disabled
00078    * @see org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#getConnection()
00079    */
00080   public Connection getConnection() throws UnreachableBackendException
00081   {
00082     if (!initialized)
00083     {
00084       logger.error(Translate.get("connection.request.not.initialized"));
00085       return null;
00086     }
00087 
00088     try
00089     { // Both freeConnections and activeConnections are synchronized
00090       Connection c = (Connection) freeConnections.pop();
00091       activeConnections.add(c);
00092       return c;
00093     }
00094     catch (EmptyStackException e)
00095     {
00096       synchronized (this)
00097       {
00098         int missing = poolSize
00099             - (activeConnections.size() + freeConnections.size());
00100         if (missing > 0)
00101         { // Re-allocate missing connections
00102           logger.info(Translate.get("connection.reallocate.missing", missing));
00103           Connection connectionToBeReturned = null;
00104           while (missing > 0)
00105           {
00106             Connection c = getConnectionFromDriver();
00107             if (c == null)
00108             {
00109               if (missing == poolSize)
00110               {
00111                 logger.error(Translate.get("connection.backend.unreachable",
00112                     backendName));
00113                 throw new UnreachableBackendException();
00114               }
00115               logger.warn(Translate
00116                   .get("connection.reallocate.failed", missing));
00117               break;
00118             }
00119             else
00120             {
00121               if (connectionToBeReturned == null)
00122                 connectionToBeReturned = c;
00123               else
00124                 freeConnections.add(c);
00125             }
00126             missing--;
00127           }
00128           return connectionToBeReturned;
00129         }
00130       }
00131       if (logger.isWarnEnabled())
00132         logger.warn(Translate.get("connection.backend.out.of.connections",
00133             new String[]{backendName, String.valueOf(poolSize)}));
00134       return null;
00135     }
00136   }
00137 
00138   /**
00139    * @see org.objectweb.cjdbc.controller.connection.AbstractPoolConnectionManager#releaseConnection(Connection)
00140    */
00141   public synchronized void releaseConnection(Connection c)
00142   {
00143     if (!initialized)
00144       return; // We probably have been disabled
00145 
00146     if (activeConnections.remove(c))
00147       freeConnections.push(c);
00148     else
00149       logger.error(Translate.get("connection.release.failed", c.toString()));
00150   }
00151 
00152   /**
00153    * @see org.objectweb.cjdbc.controller.connection.AbstractPoolConnectionManager#deleteConnection(Connection)
00154    */
00155   public synchronized void deleteConnection(Connection c)
00156   {
00157     if (!initialized)
00158       return; // We probably have been disabled
00159 
00160     if (activeConnections.remove(c))
00161     {
00162       Connection newConnection = getConnectionFromDriver();
00163       if (newConnection == null)
00164       {
00165         if (logger.isDebugEnabled())
00166           logger.error(Translate
00167               .get("connection.replaced.failed", c.toString()));
00168       }
00169       else
00170       {
00171         freeConnections.push(newConnection);
00172         if (logger.isDebugEnabled())
00173           logger.debug(Translate.get("connection.replaced.success", c
00174               .toString()));
00175       }
00176     }
00177     else
00178       logger.error(Translate.get("connection.replaced.failed.exception", c
00179           .toString()));
00180   }
00181 
00182   /**
00183    * @see org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#getXmlImpl()
00184    */
00185   public String getXmlImpl()
00186   {
00187     StringBuffer info = new StringBuffer();
00188     info.append("<" + DatabasesXmlTags.ELT_FailFastPoolConnectionManager + " "
00189         + DatabasesXmlTags.ATT_poolSize + "=\"" + poolSize / 1000 + "\"/>");
00190     return info.toString();
00191   }
00192 
00193   /**
00194    * @see java.lang.Object#clone()
00195    */
00196   protected Object clone() throws CloneNotSupportedException
00197   {
00198     return new FailFastPoolConnectionManager(backendUrl, backendName, rLogin,
00199         rPassword, driverPath, driverClassName, poolSize);
00200   }
00201 }

Generated on Mon Apr 11 22:01:32 2005 for C-JDBC by  doxygen 1.3.9.1