KickJava   Java API By Example, From Geeks To Geeks.

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


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_LPRF load balancer. This load balancer
38  * chooses the node that has the least pending queries for read and write
39  * queries execution.
40  *
41  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
42  * @version 1.0
43  */

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

53   public ParallelDB_LPRF(VirtualDatabase vdb) throws Exception JavaDoc
54   {
55     super(vdb);
56   }
57
58   /**
59    * @see org.continuent.sequoia.controller.loadbalancer.paralleldb.ParallelDB#chooseBackendForReadRequest(org.continuent.sequoia.controller.requests.AbstractRequest)
60    */

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

79     // Note that vdb lock is released in the finally clause of this try/catch
80
// block
81
try
82     {
83       ArrayList JavaDoc backends = vdb.getBackends();
84       int size = backends.size();
85
86       if (size == 0)
87         throw new NoMoreBackendException(Translate.get(
88             "loadbalancer.execute.no.backend.available", request.getId()));
89
90       // Choose the backend that has the least pending requests
91
int leastRequests = 0;
92       for (int i = 0; i < size; i++)
93       {
94         DatabaseBackend b = (DatabaseBackend) backends.get(i);
95         if (b.isReadEnabled())
96         {
97           int pending = b.getPendingRequests().size();
98           if ((backend == null) || (pending < leastRequests))
99           {
100             backend = b;
101             if (pending == 0)
102               break; // Stop here we will never find a less loaded node
103
else
104               leastRequests = pending;
105           }
106         }
107       }
108
109       if (backend == null)
110         throw new SQLException JavaDoc(Translate.get(
111             "loadbalancer.execute.no.backend.enabled", request.getId()));
112     }
113     catch (RuntimeException JavaDoc e)
114     {
115       String JavaDoc msg = Translate.get("loadbalancer.execute.find.backend.failed",
116           new String JavaDoc[]{request.getSqlShortForm(vdb.getSqlShortFormLength()),
117               e.getMessage()});
118       logger.error(msg, e);
119       throw new SQLException JavaDoc(msg);
120     }
121     finally
122     {
123       vdb.releaseReadLockBackendLists();
124     }
125
126     return backend;
127   }
128
129   /**
130    * @see org.continuent.sequoia.controller.loadbalancer.paralleldb.ParallelDB#chooseBackendForWriteRequest(org.continuent.sequoia.controller.requests.AbstractWriteRequest)
131    */

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

150     // Note that vdb lock is released in the finally clause of this try/catch
151
// block
152
try
153     {
154       ArrayList JavaDoc backends = vdb.getBackends();
155       int size = backends.size();
156
157       if (size == 0)
158         throw new NoMoreBackendException(Translate.get(
159             "loadbalancer.execute.no.backend.available", request.getId()));
160
161       // Choose the backend that has the least pending requests
162
int leastRequests = 0;
163       for (int i = 0; i < size; i++)
164       {
165         DatabaseBackend b = (DatabaseBackend) backends.get(i);
166         if (b.isWriteEnabled() && !b.isDisabling())
167         {
168           int pending = b.getPendingRequests().size();
169           if ((backend == null) || (pending < leastRequests))
170           {
171             backend = b;
172             if (pending == 0)
173               break; // Stop here we will never find a less loaded node
174
else
175               leastRequests = pending;
176           }
177         }
178       }
179
180       if (backend == null)
181       {
182         throw new SQLException JavaDoc(Translate.get(
183             "loadbalancer.execute.no.backend.enabled", request.getId()));
184       }
185     }
186     catch (RuntimeException JavaDoc e)
187     {
188       String JavaDoc msg = Translate.get("loadbalancer.execute.find.backend.failed",
189           new String JavaDoc[]{request.getSqlShortForm(vdb.getSqlShortFormLength()),
190               e.getMessage()});
191       logger.error(msg, e);
192       throw new SQLException JavaDoc(msg);
193     }
194     finally
195     {
196       vdb.releaseReadLockBackendLists();
197     }
198
199     return backend;
200   }
201
202   /**
203    * @see org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer#getInformation()
204    */

205   public String JavaDoc getInformation()
206   {
207     // We don't lock since we don't need a top accurate value
208
int size = vdb.getBackends().size();
209
210     if (size == 0)
211       return "ParallelDB Least Pending Request First Request load balancer: !!!Warning!!! No backend nodes found\n";
212     else
213       return "ParallelDB Least Pending Request First Request load balancer ("
214           + size + " backends)\n";
215   }
216
217   /**
218    * @see org.continuent.sequoia.controller.loadbalancer.paralleldb.ParallelDB#getParallelDBXml()
219    */

220   public String JavaDoc getParallelDBXml()
221   {
222     return "<" + DatabasesXmlTags.ELT_ParallelDB_LeastPendingRequestsFirst
223         + "/>";
224   }
225 }
Popular Tags