1 22 23 package org.continuent.sequoia.controller.loadbalancer.raidb1; 24 25 import java.sql.SQLException ; 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 29 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 30 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 31 import org.continuent.sequoia.common.i18n.Translate; 32 import org.continuent.sequoia.common.xml.DatabasesXmlTags; 33 import org.continuent.sequoia.controller.backend.DatabaseBackend; 34 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 35 import org.continuent.sequoia.controller.backend.result.ExecuteResult; 36 import org.continuent.sequoia.controller.cache.metadata.MetadataCache; 37 import org.continuent.sequoia.controller.loadbalancer.WeightedBalancer; 38 import org.continuent.sequoia.controller.loadbalancer.policies.WaitForCompletionPolicy; 39 import org.continuent.sequoia.controller.requests.AbstractRequest; 40 import org.continuent.sequoia.controller.requests.SelectRequest; 41 import org.continuent.sequoia.controller.requests.StoredProcedure; 42 import org.continuent.sequoia.controller.virtualdatabase.VirtualDatabase; 43 44 65 public class RAIDb1_WRR extends RAIDb1 66 { 67 76 private HashMap weights = new HashMap (); 77 private int currentWeight; 78 79 82 83 91 public RAIDb1_WRR(VirtualDatabase vdb, 92 WaitForCompletionPolicy waitForCompletionPolicy) throws Exception  93 { 94 super(vdb, waitForCompletionPolicy); 95 currentWeight = 0; 96 } 97 98 101 102 109 public ControllerResultSet execSingleBackendReadRequest( 110 SelectRequest request, MetadataCache metadataCache) throws SQLException  111 { 112 return (ControllerResultSet) executeWRR(request, STATEMENT_EXECUTE_QUERY, 113 "Request ", metadataCache); 114 } 115 116 124 public ControllerResultSet readOnlyCallableStatementExecuteQuery( 125 StoredProcedure proc, MetadataCache metadataCache) throws SQLException  126 { 127 return (ControllerResultSet) executeWRR(proc, 128 CALLABLE_STATEMENT_EXECUTE_QUERY, "Stored procedure ", metadataCache); 129 } 130 131 139 public ExecuteResult readOnlyCallableStatementExecute(StoredProcedure proc, 140 MetadataCache metadataCache) throws SQLException  141 { 142 return (ExecuteResult) executeWRR(proc, CALLABLE_STATEMENT_EXECUTE, 143 "Stored procedure ", metadataCache); 144 } 145 146 160 private Object executeWRR(AbstractRequest request, int callType, 161 String errorMsgPrefix, MetadataCache metadataCache) throws SQLException  162 { 163 try 165 { 166 vdb.acquireReadLockBackendLists(); 167 } 168 catch (InterruptedException e) 169 { 170 String msg = Translate.get( 171 "loadbalancer.backendlist.acquire.readlock.failed", e); 172 logger.error(msg); 173 throw new SQLException (msg); 174 } 175 176 DatabaseBackend backend = null; 177 178 try 181 { 182 ArrayList backends = vdb.getBackends(); 183 int size = backends.size(); 184 185 if (size == 0) 186 throw new NoMoreBackendException(Translate.get( 187 "loadbalancer.execute.no.backend.available", request.getId())); 188 189 int w = 0; boolean backendFound = false; 192 for (int i = 0; i < size; i++) 193 { 194 DatabaseBackend b = (DatabaseBackend) backends.get(i); 195 if (b.isReadEnabled()) 196 { 197 if (backend == null) 198 backend = b; 200 Integer weight = (Integer ) weights.get(b.getName()); 202 if (weight == null) 203 logger.error("No weight defined for backend " + b.getName()); 204 else 205 { 206 int backendWeight = weight.intValue(); 207 if (backendWeight == 0) 208 continue; else 210 w += backendWeight; 211 } 212 213 if (currentWeight < w) 215 { 216 backend = b; 217 backendFound = true; 218 break; 219 } 220 } 221 } 222 223 if (backend == null) 224 throw new NoMoreBackendException(Translate.get( 225 "loadbalancer.execute.no.backend.enabled", request.getId())); 226 227 if (backendFound) 231 currentWeight++; else 233 currentWeight = 1; 234 } 235 catch (RuntimeException e) 236 { 237 String msg = Translate.get("loadbalancer.execute.find.backend.failed", 238 new String []{request.getSqlShortForm(vdb.getSqlShortFormLength()), 239 e.getMessage()}); 240 logger.error(msg, e); 241 throw new SQLException (msg); 242 } 243 finally 244 { 245 vdb.releaseReadLockBackendLists(); 246 } 247 248 try 250 { 251 switch (callType) 252 { 253 case STATEMENT_EXECUTE_QUERY : 254 return executeRequestOnBackend((SelectRequest) request, backend, 255 metadataCache); 256 case CALLABLE_STATEMENT_EXECUTE_QUERY : 257 return executeStoredProcedureOnBackend((StoredProcedure) request, 258 true, backend, metadataCache); 259 case CALLABLE_STATEMENT_EXECUTE : 260 return executeStoredProcedureOnBackend((StoredProcedure) request, 261 false, backend, metadataCache); 262 default : 263 throw new RuntimeException ("Unhandled call type " + callType 264 + " in executeRoundRobin"); 265 } 266 } 267 catch (UnreachableBackendException urbe) 268 { 269 return executeWRR(request, callType, errorMsgPrefix, metadataCache); 271 } 272 catch (SQLException se) 273 { 274 String msg = Translate.get("loadbalancer.something.failed", new String []{ 275 errorMsgPrefix, String.valueOf(request.getId()), se.getMessage()}); 276 if (logger.isInfoEnabled()) 277 logger.info(msg); 278 throw se; 279 } 280 catch (RuntimeException e) 281 { 282 String msg = Translate.get("loadbalancer.something.failed.on", 283 new String []{errorMsgPrefix, 284 request.getSqlShortForm(vdb.getSqlShortFormLength()), 285 backend.getName(), e.getMessage()}); 286 logger.error(msg, e); 287 throw new SQLException (msg); 288 } 289 } 290 291 294 295 299 public void setWeight(String name, int w) throws SQLException  300 { 301 if (logger.isDebugEnabled()) 302 logger.debug(Translate.get("loadbalancer.weight.set", new String []{ 303 String.valueOf(w), name})); 304 305 weights.put(name, new Integer (w)); 306 } 307 308 311 312 317 public String getInformation() 318 { 319 int size = vdb.getBackends().size(); 321 322 if (size == 0) 323 return "RAIDb-1 with Weighted Round Robin Request load balancer: !!!Warning!!! No backend nodes found\n"; 324 else 325 return "RAIDb-1 Weighted Round-Robin Request load balancer (" + size 326 + " backends)\n"; 327 } 328 329 332 public String getRaidb1Xml() 333 { 334 return WeightedBalancer.getRaidbXml(weights, 335 DatabasesXmlTags.ELT_RAIDb_1_WeightedRoundRobin); 336 } 337 338 } 339 | Popular Tags |