KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > core > shutdown > VirtualDatabaseShutdownThread


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Nicolas Modrzyk.
22  * Contributor(s): Emmanuel Cecchet.
23  */

24
25 package org.objectweb.cjdbc.controller.core.shutdown;
26
27 import java.sql.SQLException JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Date JavaDoc;
30
31 import org.objectweb.cjdbc.common.i18n.Translate;
32 import org.objectweb.cjdbc.controller.cache.result.AbstractResultCache;
33 import org.objectweb.cjdbc.controller.recoverylog.RecoveryLog;
34 import org.objectweb.cjdbc.controller.virtualdatabase.DistributedVirtualDatabase;
35 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
36 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabaseWorkerThread;
37
38 /**
39  * Abstract class for all implementations of virtual database shutdown
40  * strategies.
41  *
42  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
43  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
44  * @version 1.0
45  */

46 public abstract class VirtualDatabaseShutdownThread extends ShutdownThread
47 {
48   protected VirtualDatabase virtualDatabase;
49
50   /**
51    * Prepare the thread for shutting down.
52    *
53    * @param vdb the database to shutdown
54    * @param level Constants.SHUTDOWN_WAIT, Constants.SHUTDOWN_SAFE or
55    * Constants.SHUTDOWN_FORCE
56    */

57   public VirtualDatabaseShutdownThread(VirtualDatabase vdb, int level)
58   {
59     super(level);
60     this.virtualDatabase = vdb;
61   }
62
63   /**
64    * Shutdown the result cache, recovery log and close the distributed virtual
65    * database group communication channel (if the virtual database is
66    * distributed).
67    */

68   protected void shutdownCacheRecoveryLogAndGroupCommunication()
69   {
70     // Shutdown the result cache
71
AbstractResultCache resultCache = virtualDatabase.getRequestManager()
72         .getResultCache();
73     if (resultCache != null)
74       resultCache.shutdown();
75
76     // Shutdown the recovery log
77
RecoveryLog recoveryLog = virtualDatabase.getRequestManager()
78         .getRecoveryLog();
79     if (recoveryLog != null)
80       recoveryLog.shutdown();
81
82     if (virtualDatabase.isDistributed())
83     {
84       logger.info("Shutting down group communication");
85       try
86       {
87         ((DistributedVirtualDatabase) virtualDatabase).quitChannel();
88       }
89       catch (Exception JavaDoc e)
90       {
91         logger
92             .warn(
93                 "An error occured while shutting down the group communication channel",
94                 e);
95       }
96     }
97   }
98
99   /**
100    * Disable all database backends with a checkpoint named after the current
101    * time if a recovery log is available.
102    */

103   protected void disableAllBackends()
104   {
105     if (virtualDatabase.getRequestManager().getRecoveryLog() != null)
106     {
107       try
108       { // disable and checkpoint for recovery log
109
virtualDatabase.storeBackendsInfo();
110         virtualDatabase.disableAllBackendsWithCheckpoint(new Date JavaDoc().toString());
111       }
112       catch (Exception JavaDoc ve)
113       {
114         logger.error(Translate
115             .get("controller.shutdown.backends.exception", ve));
116       }
117     }
118     else
119     { // no recovery log, so just disable backends
120
try
121       {
122         virtualDatabase.disableAllBackends();
123       }
124       catch (Exception JavaDoc vde)
125       {
126         logger.error(Translate.get("controller.shutdown.backends.exception",
127             vde));
128       }
129     }
130   }
131
132   /**
133    * Terminate the VirtualDatabaseWorkerThreads
134    */

135   protected void terminateVirtualDatabaseWorkerThreads()
136   {
137     ArrayList JavaDoc threads = virtualDatabase.getActiveThreads();
138     logger.info(Translate.get("controller.shutdown.active.threads", threads
139         .size()));
140     VirtualDatabaseWorkerThread wt;
141     synchronized (threads)
142     {
143       for (int i = 0; i < threads.size(); i++)
144       {
145         if (logger.isDebugEnabled())
146           logger.debug(Translate.get("controller.shutdown.database.thread",
147               new String JavaDoc[]{virtualDatabase.getVirtualDatabaseName(),
148                   String.valueOf(i)}));
149         wt = ((VirtualDatabaseWorkerThread) threads.get(i));
150         wt.shutdown();
151       }
152       threads.clear();
153     }
154
155     // Kill inactive threads
156
virtualDatabase.setPoolConnectionThreads(false);
157     ArrayList JavaDoc idleThreads = virtualDatabase.getPendingConnections();
158     synchronized (idleThreads)
159     {
160       idleThreads.notifyAll();
161     }
162   }
163
164   /**
165    * Wait for all VirtualDatabaseWorkerThreads to terminate when all clients
166    * have disconnected.
167    */

168   protected void waitForClientsToDisconnect()
169   {
170     boolean wait = true;
171     while (wait)
172     {
173       ArrayList JavaDoc threads = virtualDatabase.getActiveThreads();
174       synchronized (threads)
175       {
176         int nbThreads = threads.size();
177         if (logger.isDebugEnabled())
178           logger.debug(Translate.get("controller.shutdown.active.threads",
179               nbThreads));
180         if (nbThreads == 0)
181           wait = false;
182       }
183       if (wait)
184       {
185         synchronized (this)
186         {
187           try
188           {
189             wait(1000);
190           }
191           catch (InterruptedException JavaDoc e)
192           {
193             // Ignore
194
}
195         }
196       }
197     }
198   }
199
200   /**
201    * Wait for currently open transactions and pending writes to complete (in
202    * this order: 1.transaction, 2.writes).
203    */

204   protected void waitForTransactionsAndWritesToComplete()
205   {
206     try
207     {
208       virtualDatabase.getRequestManager().getScheduler()
209           .suspendNewTransactionsForCheckpoint();
210     }
211     catch (SQLException JavaDoc e)
212     {
213       logger
214           .error(
215               "An error occured while waiting for current transactions to complete.",
216               e);
217     }
218     try
219     {
220       virtualDatabase.getRequestManager().getScheduler().suspendWrites();
221     }
222     catch (SQLException JavaDoc e)
223     {
224       logger.error(
225           "An error occured while waiting for pending writes to complete.", e);
226     }
227   }
228
229 }
Popular Tags