00001
00025
package org.objectweb.cjdbc.controller.loadbalancer.raidb1;
00026
00027
import java.sql.SQLException;
00028
import java.util.ArrayList;
00029
import java.util.HashMap;
00030
00031
import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException;
00032
import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException;
00033
import org.objectweb.cjdbc.common.i18n.Translate;
00034
import org.objectweb.cjdbc.common.sql.AbstractRequest;
00035
import org.objectweb.cjdbc.common.sql.SelectRequest;
00036
import org.objectweb.cjdbc.common.sql.StoredProcedure;
00037
import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00038
import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
00039
import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache;
00040
import org.objectweb.cjdbc.controller.loadbalancer.WeightedBalancer;
00041
import org.objectweb.cjdbc.controller.loadbalancer.policies.WaitForCompletionPolicy;
00042
import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
00043
import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
00044
00057 public class RAIDb1_WRR extends RAIDb1
00058 {
00059
00060
00061
00062
00063
00064 private HashMap
weights =
new HashMap();
00065 private int index;
00066
00067
00068
00069
00070
00071
00072
00081 public RAIDb1_WRR(
VirtualDatabase vdb,
00082
WaitForCompletionPolicy waitForCompletionPolicy)
throws SQLException
00083 {
00084 super(vdb, waitForCompletionPolicy);
00085
index = -1;
00086 }
00087
00088
00089
00090
00091
00099 public ControllerResultSet execReadRequest(
SelectRequest request,
00100
MetadataCache metadataCache)
throws SQLException
00101 {
00102
return executeWRR(request,
true,
"Request ", metadataCache);
00103 }
00104
00113 public ControllerResultSet execReadOnlyReadStoredProcedure(
00114
StoredProcedure proc,
MetadataCache metadataCache)
throws SQLException
00115 {
00116
return executeWRR(proc,
false,
"Stored procedure ", metadataCache);
00117 }
00118
00133 private ControllerResultSet executeWRR(
AbstractRequest request,
00134
boolean isSelect, String errorMsgPrefix,
MetadataCache metadataCache)
00135
throws SQLException
00136 {
00137
00138
try
00139 {
00140 vdb.
acquireReadLockBackendLists();
00141 }
00142
catch (InterruptedException e)
00143 {
00144 String msg =
Translate.get(
00145
"loadbalancer.backendlist.acquire.readlock.failed", e);
00146 logger.
error(msg);
00147
throw new SQLException(msg);
00148 }
00149
00150
DatabaseBackend backend = null;
00151
00152
00153
00154
try
00155 {
00156 ArrayList backends = vdb.
getBackends();
00157
int size = backends.size();
00158
00159
if (size == 0)
00160
throw new SQLException(
Translate.get(
00161
"loadbalancer.execute.no.backend.available", request.getId()));
00162
00163
00164
int w = 0;
00165
for (
int i = 0; i < size; i++)
00166 {
00167
DatabaseBackend b = (
DatabaseBackend) backends.get(
index);
00168
if (b.
isReadEnabled())
00169 {
00170
if (backend == null)
00171 backend = b;
00172
00173
00174 Integer weight = (Integer)
weights.get(b.getName());
00175
if (weight == null)
00176 logger.
error(
"No weight defined for backend " + b.getName());
00177
else
00178 w += weight.intValue();
00179
00180
00181
if (
index <= w)
00182 {
00183 backend = b;
00184
index++;
00185
break;
00186 }
00187 }
00188 }
00189
00190
if (backend == null)
00191
throw new NoMoreBackendException(
Translate.get(
00192
"loadbalancer.execute.no.backend.enabled", request.getId()));
00193
00194
00195
00196
00197
if (
index > w)
00198
index = 1;
00199 }
00200
catch (RuntimeException e)
00201 {
00202 String msg =
Translate.get(
"loadbalancer.execute.find.backend.failed",
00203
new String[]{request.getSQLShortForm(vdb.
getSQLShortFormLength()),
00204 e.getMessage()});
00205 logger.
error(msg, e);
00206
throw new SQLException(msg);
00207 }
00208 finally
00209 {
00210 vdb.
releaseReadLockBackendLists();
00211 }
00212
00213
ControllerResultSet rs = null;
00214
00215
try
00216 {
00217
if (isSelect)
00218 rs =
executeRequestOnBackend((
SelectRequest) request, backend,
00219 metadataCache);
00220
else
00221 rs =
executeStoredProcedureOnBackend((
StoredProcedure) request,
00222 backend, metadataCache);
00223 }
00224
catch (UnreachableBackendException urbe)
00225 {
00226
00227
return executeWRR(request, isSelect, errorMsgPrefix, metadataCache);
00228 }
00229
catch (SQLException se)
00230 {
00231 String msg = Translate.get(
"loadbalancer.something.failed",
new String[]{
00232 errorMsgPrefix, String.valueOf(request.getId()), se.getMessage()});
00233
if (logger.isInfoEnabled())
00234 logger.info(msg);
00235
throw new SQLException(msg);
00236 }
00237
catch (RuntimeException e)
00238 {
00239 String msg = Translate.get(
"loadbalancer.something.failed.on",
00240
new String[]{errorMsgPrefix,
00241 request.getSQLShortForm(vdb.getSQLShortFormLength()),
00242 backend.getName(), e.getMessage()});
00243 logger.error(msg, e);
00244
throw new SQLException(msg);
00245 }
00246
00247
return rs;
00248 }
00249
00250
00251
00252
00253
00258 public void setWeight(String name,
int w)
throws SQLException
00259 {
00260
if (logger.isDebugEnabled())
00261 logger.debug(
Translate.get(
"loadbalancer.weight.set",
new String[]{
00262 String.valueOf(w), name}));
00263
00264 weights.put(name,
new Integer(w));
00265 }
00266
00267
00268
00269
00270
00276 public String getInformation()
00277 {
00278
00279
int size = vdb.getBackends().size();
00280
00281
if (size == 0)
00282
return "RAIDb-1 with Weighted Round Robin Request load balancer: !!!Warning!!! No backend nodes found\n";
00283
else
00284
return "RAIDb-1 Weighted Round-Robin Request load balancer (" + size
00285 +
" backends)\n";
00286 }
00287
00291 public String getRaidb1Xml()
00292 {
00293
return WeightedBalancer.getRaidbXml(weights,
00294
DatabasesXmlTags.ELT_RAIDb_1_WeightedRoundRobin);
00295 }
00296
00297 }