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

VirtualDatabaseShutdownThread.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2005 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): Nicolas Modrzyk. 
00022  * Contributor(s): Emmanuel Cecchet.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.core.shutdown;
00026 
00027 import java.sql.SQLException;
00028 import java.util.ArrayList;
00029 import java.util.Date;
00030 
00031 import org.objectweb.cjdbc.common.i18n.Translate;
00032 import org.objectweb.cjdbc.controller.virtualdatabase.DistributedVirtualDatabase;
00033 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
00034 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabaseWorkerThread;
00035 
00036 /**
00037  * Abstract class for all implementations of virtual database shutdown
00038  * strategies.
00039  * 
00040  * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
00041  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
00042  * @version 1.0
00043  */
00044 public abstract class VirtualDatabaseShutdownThread extends ShutdownThread
00045 {
00046   protected VirtualDatabase virtualDatabase;
00047 
00048   /**
00049    * Prepare the thread for shutting down.
00050    * 
00051    * @param vdb the database to shutdown
00052    * @param level Constants.SHUTDOWN_WAIT, Constants.SHUTDOWN_SAFE or
00053    *          Constants.SHUTDOWN_FORCE
00054    */
00055   public VirtualDatabaseShutdownThread(VirtualDatabase vdb, int level)
00056   {
00057     super(level);
00058     this.virtualDatabase = vdb;
00059   }
00060 
00061   /**
00062    * Close the virtual database channel.
00063    */
00064   protected void closeVirtualDatabase()
00065   {
00066     if (virtualDatabase.isDistributed())
00067     {
00068       logger.info("Shutting down group communication");
00069       try
00070       {
00071         ((DistributedVirtualDatabase) virtualDatabase).quitChannel();
00072       }
00073       catch (Exception e)
00074       {
00075         logger
00076             .warn(
00077                 "An error occured while shutting down the group communication channel",
00078                 e);
00079       }
00080     }
00081   }
00082 
00083   /**
00084    * Disable all database backends with a checkpoint named after the current
00085    * time if a recovery log is available.
00086    */
00087   protected void disableAllBackends()
00088   {
00089     if (virtualDatabase.getRequestManager().getRecoveryLog() != null)
00090     {
00091       try
00092       { // disable and checkpoint for recovery log
00093         virtualDatabase.storeBackendsInfo();
00094         virtualDatabase.disableAllBackendsWithCheckpoint(new Date().toString());
00095       }
00096       catch (Exception ve)
00097       {
00098         logger.error(Translate
00099             .get("controller.shutdown.backends.exception", ve));
00100       }
00101     }
00102     else
00103     { // no recovery log, so just disable backends
00104       try
00105       {
00106         virtualDatabase.disableAllBackends();
00107       }
00108       catch (Exception vde)
00109       {
00110         logger.error(Translate.get("controller.shutdown.backends.exception",
00111             vde));
00112       }
00113     }
00114   }
00115 
00116   /**
00117    * Terminate the VirtualDatabaseWorkerThreads
00118    */
00119   protected void terminateVirtualDatabaseWorkerThreads()
00120   {
00121     ArrayList threads = virtualDatabase.getActiveThreads();
00122     logger.info(Translate.get("controller.shutdown.active.threads", threads
00123         .size()));
00124     VirtualDatabaseWorkerThread wt;
00125     synchronized (threads)
00126     {
00127       for (int i = 0; i < threads.size(); i++)
00128       {
00129         if (logger.isDebugEnabled())
00130           logger.debug(Translate.get("controller.shutdown.database.thread",
00131               new String[]{virtualDatabase.getVirtualDatabaseName(),
00132                   String.valueOf(i)}));
00133         wt = ((VirtualDatabaseWorkerThread) threads.get(i));
00134         wt.shutdown();
00135       }
00136     }
00137     virtualDatabase.getActiveThreads().clear();
00138   }
00139 
00140   /**
00141    * Wait for all VirtualDatabaseWorkerThreads to terminate when all clients
00142    * have disconnected.
00143    */
00144   protected void waitForClientsToDisconnect()
00145   {
00146     boolean wait = true;
00147     while (wait)
00148     {
00149       ArrayList threads = virtualDatabase.getActiveThreads();
00150       synchronized (threads)
00151       {
00152         int nbThreads = threads.size();
00153         logger.debug(Translate.get("controller.shutdown.active.threads", ""
00154             + nbThreads));
00155         if (nbThreads == 0)
00156         {
00157           wait = false;
00158         }
00159       }
00160       if (wait)
00161       {
00162         synchronized (this)
00163         {
00164           try
00165           {
00166             wait(1000);
00167           }
00168           catch (InterruptedException e)
00169           {
00170             // Ignore
00171           }
00172         }
00173       }
00174     }
00175   }
00176 
00177   /**
00178    * Wait for currently open transactions and pending writes to complete (in
00179    * this order: 1.transaction, 2.writes).
00180    */
00181   protected void waitForTransactionsAndWritesToComplete()
00182   {
00183     try
00184     {
00185       virtualDatabase.getRequestManager().getScheduler()
00186           .suspendNewTransactionsForCheckpoint();
00187     }
00188     catch (SQLException e)
00189     {
00190       logger
00191           .error(
00192               "An error occured while waiting for current transactions to complete.",
00193               e);
00194     }
00195     try
00196     {
00197       virtualDatabase.getRequestManager().getScheduler().suspendWrites();
00198     }
00199     catch (SQLException e)
00200     {
00201       logger.error(
00202           "An error occured while waiting for pending writes to complete.", e);
00203     }
00204   }
00205 
00206 }

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