src/org/objectweb/cjdbc/controller/loadbalancer/raidb1/RAIDb1_WRR.java

説明を見る。
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 * How the code is organized ? 1. Member variables 2. Constructor(s) 3. 00061 * Request handling 4. Debug/Monitoring 00062 */ 00063 00064 private HashMap weights = new HashMap(); 00065 private int index; // index in the backend vector the 00066 00067 // Round-Robin 00068 00069 /* 00070 * Constructors 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 * Request Handling 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 // Choose a backend 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 // Note that vdb lock is released in the finally clause of this try/catch 00153 // block 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 // Choose the backend (WRR algorithm starts here) 00164 int w = 0; // cumulative weight 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; // Fallback if no backend found 00172 00173 // Add the weight of this backend 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 // Ok we reached the needed weight, take this backend 00181 if (index <= w) 00182 { 00183 backend = b; 00184 index++; // Next time take the next 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 // We are over the total weight and we are using the 00195 // first available node. Let's reset the index to 1 00196 // since we used this first node (0++). 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 // Execute the request on the chosen backend 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 // Try to execute query on different backend 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 * Backends management 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 * Debug/Monitoring 00269 */ 00270 00276 public String getInformation() 00277 { 00278 // We don't lock since we don't need a top accurate value 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 }

CJDBCversion1.0.4に対してTue Oct 12 15:16:02 2004に生成されました。 doxygen 1.3.8