KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > loadbalancer > paralleldb > ParallelDB_RR


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

22
23 package org.continuent.sequoia.controller.loadbalancer.paralleldb;
24
25 import java.sql.SQLException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 import org.continuent.sequoia.common.exceptions.NoMoreBackendException;
29 import org.continuent.sequoia.common.i18n.Translate;
30 import org.continuent.sequoia.common.xml.DatabasesXmlTags;
31 import org.continuent.sequoia.controller.backend.DatabaseBackend;
32 import org.continuent.sequoia.controller.requests.AbstractRequest;
33 import org.continuent.sequoia.controller.requests.AbstractWriteRequest;
34 import org.continuent.sequoia.controller.virtualdatabase.VirtualDatabase;
35
36 /**
37  * This class defines a ParallelDB_RR load balancer. This load balancer performs
38  * simple round-robin for read and write queries execution.
39  *
40  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
41  * @version 1.0
42  */

43 public class ParallelDB_RR extends ParallelDB
44 {
45
46   private int index = 0;
47
48   /**
49    * Creates a new <code>ParallelDB_RR</code> object
50    *
51    * @param vdb the virtual database this load balancer belongs to.
52    * @throws Exception if an error occurs
53    */

54   public ParallelDB_RR(VirtualDatabase vdb) throws Exception JavaDoc
55   {
56     super(vdb);
57   }
58
59   /**
60    * Choose a backend using a round-robin algorithm for read request execution.
61    *
62    * @param request request to execute
63    * @return the chosen backend
64    * @throws SQLException if an error occurs
65    */

66   public DatabaseBackend chooseBackendForReadRequest(AbstractRequest request)
67       throws SQLException JavaDoc
68   {
69     // Choose a backend
70
try
71     {
72       vdb.acquireReadLockBackendLists();
73     }
74     catch (InterruptedException JavaDoc e)
75     {
76       String JavaDoc msg = Translate.get(
77           "loadbalancer.backendlist.acquire.readlock.failed", e);
78       logger.error(msg);
79       throw new SQLException JavaDoc(msg);
80     }
81
82     DatabaseBackend backend = null; // The backend that will execute the query
83

84     // Note that vdb lock is released in the finally clause of this try/catch
85
// block
86
try
87     {
88       ArrayList JavaDoc backends = vdb.getBackends();
89       int size = backends.size();
90
91       if (size == 0)
92         throw new NoMoreBackendException(Translate.get(
93             "loadbalancer.execute.no.backend.available", request.getId()));
94
95       // Take the next backend
96
int maxTries = size;
97       synchronized (this)
98       {
99         do
100         {
101           index = (index + 1) % size;
102           backend = (DatabaseBackend) backends.get(index);
103           maxTries--;
104         }
105         while ((!backend.isReadEnabled() && maxTries >= 0));
106       }
107
108       if (maxTries < 0)
109         throw new SQLException JavaDoc(Translate.get(
110             "loadbalancer.execute.no.backend.enabled", request.getId()));
111     }
112     catch (RuntimeException JavaDoc e)
113     {
114       String JavaDoc msg = Translate.get("loadbalancer.execute.find.backend.failed",
115           new String JavaDoc[]{request.getSqlShortForm(vdb.getSqlShortFormLength()),
116               e.getMessage()});
117       logger.error(msg, e);
118       throw new SQLException JavaDoc(msg);
119     }
120     finally
121     {
122       vdb.releaseReadLockBackendLists();
123     }
124     return backend;
125   }
126
127   /**
128    * Choose a backend using a round-robin algorithm for write request execution.
129    *
130    * @param request request to execute
131    * @return the chosen backend
132    * @throws SQLException if an error occurs
133    */

134   public DatabaseBackend chooseBackendForWriteRequest(
135       AbstractWriteRequest request) throws SQLException JavaDoc
136   {
137     // Choose a backend
138
try
139     {
140       vdb.acquireReadLockBackendLists();
141     }
142     catch (InterruptedException JavaDoc e)
143     {
144       String JavaDoc msg = Translate.get(
145           "loadbalancer.backendlist.acquire.readlock.failed", e);
146       logger.error(msg);
147       throw new SQLException JavaDoc(msg);
148     }
149
150     DatabaseBackend backend = null; // The backend that will execute the query
151

152     // Note that vdb lock is released in the finally clause of this try/catch
153
// block
154
try
155     {
156       ArrayList JavaDoc backends = vdb.getBackends();
157       int size = backends.size();
158
159       if (size == 0)
160         throw new NoMoreBackendException(Translate.get(
161             "loadbalancer.execute.no.backend.available", request.getId()));
162
163       // Take the next backend
164
int maxTries = size;
165       synchronized (this)
166       {
167         do
168         {
169           index = (index + 1) % size;
170           backend = (DatabaseBackend) backends.get(index);
171           maxTries--;
172         }
173         while ((!backend.isWriteEnabled() || backend.isDisabling())
174             && (maxTries >= 0));
175       }
176
177       if (maxTries < 0)
178         throw new SQLException JavaDoc(Translate.get(
179             "loadbalancer.execute.no.backend.enabled", request.getId()));
180     }
181     catch (RuntimeException JavaDoc e)
182     {
183       String JavaDoc msg = Translate.get("loadbalancer.execute.find.backend.failed",
184           new String JavaDoc[]{request.getSqlShortForm(vdb.getSqlShortFormLength()),
185               e.getMessage()});
186       logger.error(msg, e);
187       throw new SQLException JavaDoc(msg);
188     }
189     finally
190     {
191       vdb.releaseReadLockBackendLists();
192     }
193     return backend;
194   }
195
196   /**
197    * @see org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer#getInformation()
198    */

199   public String JavaDoc getInformation()
200   {
201     // We don't lock since we don't need a top accurate value
202
int size = vdb.getBackends().size();
203
204     if (size == 0)
205       return "ParallelDB Round-Robin Request load balancer: !!!Warning!!! No backend nodes found\n";
206     else
207       return "ParallelDB Round-Robin Request load balancer (" + size
208           + " backends)\n";
209   }
210
211   /**
212    * @see org.continuent.sequoia.controller.loadbalancer.paralleldb.ParallelDB#getParallelDBXml()
213    */

214   public String JavaDoc getParallelDBXml()
215   {
216     return "<" + DatabasesXmlTags.ELT_ParallelDB_RoundRobin + "/>";
217   }
218 }
Popular Tags