00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
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
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 public RAIDb1_WRR(VirtualDatabase vdb,
00083 WaitForCompletionPolicy waitForCompletionPolicy) throws Exception
00084 {
00085 super(vdb, waitForCompletionPolicy);
00086 index = -1;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 public ControllerResultSet execReadRequest(SelectRequest request,
00101 MetadataCache metadataCache) throws SQLException
00102 {
00103 return executeWRR(request, true, "Request ", metadataCache);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 public ControllerResultSet execReadOnlyReadStoredProcedure(
00115 StoredProcedure proc, MetadataCache metadataCache) throws SQLException
00116 {
00117 return executeWRR(proc, false, "Stored procedure ", metadataCache);
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 private ControllerResultSet executeWRR(AbstractRequest request,
00135 boolean isSelect, String errorMsgPrefix, MetadataCache metadataCache)
00136 throws SQLException
00137 {
00138
00139 try
00140 {
00141 vdb.acquireReadLockBackendLists();
00142 }
00143 catch (InterruptedException e)
00144 {
00145 String msg = Translate.get(
00146 "loadbalancer.backendlist.acquire.readlock.failed", e);
00147 logger.error(msg);
00148 throw new SQLException(msg);
00149 }
00150
00151 DatabaseBackend backend = null;
00152
00153
00154
00155 try
00156 {
00157 ArrayList backends = vdb.getBackends();
00158 int size = backends.size();
00159
00160 if (size == 0)
00161 throw new SQLException(Translate.get(
00162 "loadbalancer.execute.no.backend.available", request.getId()));
00163
00164
00165 int w = 0;
00166 for (int i = 0; i < size; i++)
00167 {
00168 DatabaseBackend b = (DatabaseBackend) backends.get(index);
00169 if (b.isReadEnabled())
00170 {
00171 if (backend == null)
00172 backend = b;
00173
00174
00175 Integer weight = (Integer) weights.get(b.getName());
00176 if (weight == null)
00177 logger.error("No weight defined for backend " + b.getName());
00178 else
00179 w += weight.intValue();
00180
00181
00182 if (index <= w)
00183 {
00184 backend = b;
00185 index++;
00186 break;
00187 }
00188 }
00189 }
00190
00191 if (backend == null)
00192 throw new NoMoreBackendException(Translate.get(
00193 "loadbalancer.execute.no.backend.enabled", request.getId()));
00194
00195
00196
00197
00198 if (index > w)
00199 index = 1;
00200 }
00201 catch (RuntimeException e)
00202 {
00203 String msg = Translate.get("loadbalancer.execute.find.backend.failed",
00204 new String[]{request.getSQLShortForm(vdb.getSQLShortFormLength()),
00205 e.getMessage()});
00206 logger.error(msg, e);
00207 throw new SQLException(msg);
00208 }
00209 finally
00210 {
00211 vdb.releaseReadLockBackendLists();
00212 }
00213
00214 ControllerResultSet rs = null;
00215
00216 try
00217 {
00218 if (isSelect)
00219 rs = executeRequestOnBackend((SelectRequest) request, backend,
00220 metadataCache);
00221 else
00222 rs = executeStoredProcedureOnBackend((StoredProcedure) request,
00223 backend, metadataCache);
00224 }
00225 catch (UnreachableBackendException urbe)
00226 {
00227
00228 return executeWRR(request, isSelect, errorMsgPrefix, metadataCache);
00229 }
00230 catch (SQLException se)
00231 {
00232 String msg = Translate.get("loadbalancer.something.failed", new String[]{
00233 errorMsgPrefix, String.valueOf(request.getId()), se.getMessage()});
00234 if (logger.isInfoEnabled())
00235 logger.info(msg);
00236 throw se;
00237 }
00238 catch (RuntimeException e)
00239 {
00240 String msg = Translate.get("loadbalancer.something.failed.on",
00241 new String[]{errorMsgPrefix,
00242 request.getSQLShortForm(vdb.getSQLShortFormLength()),
00243 backend.getName(), e.getMessage()});
00244 logger.error(msg, e);
00245 throw new SQLException(msg);
00246 }
00247
00248 return rs;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 public void setWeight(String name, int w) throws SQLException
00260 {
00261 if (logger.isDebugEnabled())
00262 logger.debug(Translate.get("loadbalancer.weight.set", new String[]{
00263 String.valueOf(w), name}));
00264
00265 weights.put(name, new Integer(w));
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 public String getInformation()
00278 {
00279
00280 int size = vdb.getBackends().size();
00281
00282 if (size == 0)
00283 return "RAIDb-1 with Weighted Round Robin Request load balancer: !!!Warning!!! No backend nodes found\n";
00284 else
00285 return "RAIDb-1 Weighted Round-Robin Request load balancer (" + size
00286 + " backends)\n";
00287 }
00288
00289
00290
00291
00292 public String getRaidb1Xml()
00293 {
00294 return WeightedBalancer.getRaidbXml(weights,
00295 DatabasesXmlTags.ELT_RAIDb_1_WeightedRoundRobin);
00296 }
00297
00298 }