KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > loadbalancer > paralleldb > ParallelDB_LPRF


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 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): Emmanuel Cecchet.
22  * Contributor(s): ______________________.
23  */

24
25 package org.objectweb.cjdbc.controller.loadbalancer.paralleldb;
26
27 import java.sql.SQLException JavaDoc;
28 import java.util.ArrayList JavaDoc;
29
30 import org.objectweb.cjdbc.common.i18n.Translate;
31 import org.objectweb.cjdbc.common.sql.AbstractRequest;
32 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
33 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
34 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
35 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
36
37 /**
38  * This class defines a ParallelDB_LPRF load balancer. This load balancer
39  * chooses the node that has the least pending queries for read and write
40  * queries execution.
41  *
42  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
43  * @version 1.0
44  */

45 public class ParallelDB_LPRF extends ParallelDB
46 {
47
48   /**
49    * Creates a new <code>ParallelDB_LPRF</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_LPRF(VirtualDatabase vdb) throws Exception JavaDoc
55   {
56     super(vdb);
57   }
58
59   /**
60    * @see org.objectweb.cjdbc.controller.loadbalancer.paralleldb.ParallelDB#chooseBackendForReadRequest(org.objectweb.cjdbc.common.sql.AbstractRequest)
61    */

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

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

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

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

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

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