KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > core > shutdown > VirtualDatabaseShutdownThread


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
6  * Copyright (C) 2006 Continuent, Inc.
7  * Contact: sequoia@continuent.org
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Initial developer(s): Nicolas Modrzyk.
22  * Contributor(s): Emmanuel Cecchet.
23  */

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

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

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

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

107   protected void disableAllBackendsWithCheckpoint()
108   {
109     if (virtualDatabase.getRequestManager().getRecoveryLog() != null)
110     {
111       try
112       { // disable and checkpoint for recovery log
113
virtualDatabase.disableAllBackendsWithCheckpoint(virtualDatabase
114             .buildCheckpointName("disable all backends"));
115       }
116       catch (Exception JavaDoc ve)
117       {
118         logger.error(Translate
119             .get("controller.shutdown.backends.exception", ve));
120       }
121       finally
122       {
123         virtualDatabase.storeBackendsInfo();
124       }
125     }
126     else
127     { // no recovery log, so just disable backends
128
disableAllBackendsWithoutCheckpoint();
129     }
130   }
131
132   /**
133    * Disable all backends in force mode without setting a checkpoint.
134    */

135   protected void disableAllBackendsWithoutCheckpoint()
136   {
137     try
138     {
139       virtualDatabase.disableAllBackends(true);
140     }
141     catch (Exception JavaDoc vde)
142     {
143       logger
144           .error(Translate.get("controller.shutdown.backends.exception", vde));
145     }
146   }
147
148   /**
149    * Terminate the VirtualDatabaseWorkerThreads. We actually wait for the
150    * threads to be terminated.
151    */

152   protected void terminateVirtualDatabaseWorkerThreads()
153   {
154     ArrayList JavaDoc idleThreads = virtualDatabase.getPendingConnections();
155
156     // Kill inactive threads first. As virtual database is shutting down, no new
157
// thread will be created
158
synchronized (idleThreads)
159     {
160       virtualDatabase.setPoolConnectionThreads(false);
161       idleThreads.notifyAll();
162     }
163
164     ArrayList JavaDoc threads = virtualDatabase.getActiveThreads();
165     logger.info(Translate.get("controller.shutdown.active.threads", threads
166         .size()));
167
168     boolean retry;
169     do
170     {
171       synchronized (threads)
172       {
173         // Kill active threads
174
for (int i = 0; i < threads.size(); i++)
175         {
176           if (logger.isDebugEnabled())
177             logger.debug(Translate.get("controller.shutdown.database.thread",
178                 new String JavaDoc[]{virtualDatabase.getVirtualDatabaseName(),
179                     String.valueOf(i)}));
180           ((VirtualDatabaseWorkerThread) threads.get(i)).shutdown();
181         }
182       }
183       synchronized (threads)
184       {
185         retry = threads.size() > 0;
186         if (retry)
187         {
188           try
189           {
190             threads.wait(100);
191           }
192           catch (InterruptedException JavaDoc e)
193           {
194             e.printStackTrace();
195           }
196         }
197       }
198     }
199     while (retry);
200   }
201
202   /**
203    * Wait for all VirtualDatabaseWorkerThreads to terminate when all clients
204    * have disconnected.
205    */

206   protected void waitForClientsToDisconnect()
207   {
208     boolean wait = true;
209     ArrayList JavaDoc threads = virtualDatabase.getActiveThreads();
210     while (wait)
211     {
212       synchronized (threads)
213       {
214         int nbThreads = threads.size();
215         if (logger.isDebugEnabled())
216           logger.debug(Translate.get("controller.shutdown.active.threads",
217               nbThreads));
218         if (nbThreads == 0)
219           wait = false;
220       }
221       if (wait)
222       {
223         synchronized (this)
224         {
225           try
226           {
227             wait(1000);
228           }
229           catch (InterruptedException JavaDoc e)
230           {
231             // Ignore
232
}
233         }
234       }
235     }
236   }
237
238 }
Popular Tags