1 24 25 package org.objectweb.cjdbc.controller.loadbalancer.raidb2; 26 27 import java.sql.SQLException ; 28 import java.util.ArrayList ; 29 30 import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException; 31 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException; 32 import org.objectweb.cjdbc.common.i18n.Translate; 33 import org.objectweb.cjdbc.common.sql.SelectRequest; 34 import org.objectweb.cjdbc.common.sql.StoredProcedure; 35 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 36 import org.objectweb.cjdbc.controller.backend.DatabaseBackend; 37 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache; 38 import org.objectweb.cjdbc.controller.loadbalancer.policies.WaitForCompletionPolicy; 39 import org.objectweb.cjdbc.controller.loadbalancer.policies.createtable.CreateTablePolicy; 40 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet; 41 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase; 42 43 54 public class RAIDb2_LPRF extends RAIDb2 55 { 56 57 61 62 65 66 76 public RAIDb2_LPRF(VirtualDatabase vdb, 77 WaitForCompletionPolicy waitForCompletionPolicy, 78 CreateTablePolicy createTablePolicy) throws Exception 79 { 80 super(vdb, waitForCompletionPolicy, createTablePolicy); 81 } 82 83 86 87 99 public ControllerResultSet execReadRequest(SelectRequest request, 100 MetadataCache metadataCache) throws SQLException 101 { 102 try 104 { 105 vdb.acquireReadLockBackendLists(); 106 } 107 catch (InterruptedException e) 108 { 109 String msg = Translate.get( 110 "loadbalancer.backendlist.acquire.readlock.failed", e); 111 logger.error(msg); 112 throw new SQLException (msg); 113 } 114 115 DatabaseBackend backend = null; 117 try 120 { 121 ArrayList backends = vdb.getBackends(); 122 int size = backends.size(); 123 124 if (size == 0) 125 throw new SQLException (Translate.get( 126 "loadbalancer.execute.no.backend.available", request.getId())); 127 128 int leastRequests = 0; 130 int enabledBackends = 0; 131 ArrayList tables = request.getFrom(); 132 133 for (int i = 0; i < size; i++) 134 { 135 DatabaseBackend b = (DatabaseBackend) backends.get(i); 136 if (b.isReadEnabled()) 137 { 138 enabledBackends++; 139 if (b.hasTables(tables)) 140 { 141 int pending = b.getPendingRequests().size(); 142 if (((backend == null) || (pending < leastRequests))) 143 { 144 backend = b; 145 if (pending == 0) 146 break; else 148 leastRequests = pending; 149 } 150 } 151 } 152 } 153 154 if (backend == null) 155 { 156 if (enabledBackends == 0) 157 throw new NoMoreBackendException(Translate.get( 158 "loadbalancer.execute.no.backend.enabled", request.getId())); 159 else 160 throw new SQLException (Translate.get( 161 "loadbalancer.backend.no.required.tables", tables.toString())); 162 } 163 164 } 165 catch (RuntimeException e) 166 { 167 String msg = Translate.get("loadbalancer.request.failed.on.backend", 168 new String []{request.getSQLShortForm(vdb.getSQLShortFormLength()), 169 backend.getName(), e.getMessage()}); 170 logger.error(msg, e); 171 throw new SQLException (msg); 172 } 173 finally 174 { 175 vdb.releaseReadLockBackendLists(); 176 } 177 178 ControllerResultSet rs = null; 180 try 181 { 182 rs = executeRequestOnBackend(request, backend, metadataCache); 183 } 184 catch (UnreachableBackendException se) 185 { 186 return execReadRequest(request, metadataCache); 188 } 189 catch (SQLException se) 190 { 191 String msg = Translate.get("loadbalancer.request.failed", new String []{ 192 String.valueOf(request.getId()), se.getMessage()}); 193 if (logger.isInfoEnabled()) 194 logger.info(msg); 195 throw new SQLException (msg); 196 } 197 catch (RuntimeException e) 198 { 199 String msg = Translate.get("loadbalancer.request.failed.on.backend", 200 new String []{request.getSQLShortForm(vdb.getSQLShortFormLength()), 201 backend.getName(), e.getMessage()}); 202 logger.error(msg, e); 203 throw new SQLException (msg); 204 } 205 206 return rs; 207 } 208 209 217 public ControllerResultSet execReadOnlyReadStoredProcedure( 218 StoredProcedure proc, MetadataCache metadataCache) throws SQLException 219 { 220 try 222 { 223 vdb.acquireReadLockBackendLists(); 224 } 225 catch (InterruptedException e) 226 { 227 String msg = Translate.get( 228 "loadbalancer.backendlist.acquire.readlock.failed", e); 229 logger.error(msg); 230 throw new SQLException (msg); 231 } 232 233 DatabaseBackend backend = null; 235 try 238 { 239 DatabaseBackend failedBackend = null; 240 SQLException failedException = null; 241 ControllerResultSet rs = null; 242 do 243 { 244 ArrayList backends = vdb.getBackends(); 245 int size = backends.size(); 246 247 if (size == 0) 248 throw new SQLException (Translate.get( 249 "loadbalancer.execute.no.backend.available", proc.getId())); 250 251 int leastRequests = 0; 253 int enabledBackends = 0; 254 255 for (int i = 0; i < size; i++) 256 { 257 DatabaseBackend b = (DatabaseBackend) backends.get(i); 258 if (b.isReadEnabled()) 259 { 260 enabledBackends++; 261 if (b.hasStoredProcedure(proc.getProcedureName())) 262 { 263 int pending = b.getPendingRequests().size(); 264 if ((b != failedBackend) 265 && ((backend == null) || (pending < leastRequests))) 266 { 267 backend = b; 268 if (pending == 0) 269 break; else 271 leastRequests = pending; 272 } 273 } 274 } 275 } 276 277 if (backend == null) 278 { 279 if (enabledBackends == 0) 280 throw new SQLException (Translate 281 .get("loadbalancer.storedprocedure.backend.no.enabled", proc 282 .getId())); 283 else if (failedBackend == null) 284 throw new SQLException (Translate.get( 285 "loadbalancer.backend.no.required.storedprocedure", proc 286 .getProcedureName())); 287 else 288 throw failedException; 290 } 291 292 boolean toDisable = false; 294 try 295 { 296 rs = executeStoredProcedureOnBackend(proc, backend, metadataCache); 297 if (failedBackend != null) 298 { if (logger.isWarnEnabled()) 300 logger.warn(Translate.get("loadbalancer.storedprocedure.status", 301 new String []{String.valueOf(proc.getId()), backend.getName(), 302 failedBackend.getName()})); 303 toDisable = true; 304 } 305 } 306 catch (UnreachableBackendException se) 307 { 308 continue; 310 } 311 catch (SQLException se) 312 { 313 if (failedBackend != null) 314 { String msg = Translate.get( 316 "loadbalancer.storedprocedure.failed.twice", new String []{ 317 String.valueOf(proc.getId()), se.getMessage()}); 318 if (logger.isInfoEnabled()) 319 logger.info(msg); 320 throw new SQLException (msg); 321 } 322 else 323 { failedBackend = backend; 325 failedException = se; 326 if (logger.isInfoEnabled()) 327 logger.info(Translate.get( 328 "loadbalancer.storedprocedure.failed.on.backend", 329 new String []{ 330 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 331 backend.getName(), se.getMessage()})); 332 continue; 333 } 334 } 335 336 if (toDisable) 337 { try 340 { 341 if (logger.isWarnEnabled()) 342 logger.warn(Translate.get("loadbalancer.backend.disabling", 343 failedBackend.getName())); 344 disableBackend(failedBackend); 345 } 346 catch (SQLException ignore) 347 { 348 } 349 finally 350 { 351 failedBackend = null; } 353 } 354 } 355 while (failedBackend != null); 356 return rs; 357 } 358 catch (RuntimeException e) 359 { 360 String msg = Translate.get( 361 "loadbalancer.storedprocedure.failed.on.backend", new String []{ 362 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 363 backend.getName(), e.getMessage()}); 364 logger.fatal(msg, e); 365 throw new SQLException (msg); 366 } 367 finally 368 { 369 vdb.releaseReadLockBackendLists(); 370 } 371 } 372 373 376 377 382 public String getInformation() 383 { 384 int size = vdb.getBackends().size(); 386 387 if (size == 0) 388 return "RAIDb-2 Least Pending Requests First load balancer: !!!Warning!!! No backend nodes found\n"; 389 else 390 return "RAIDb-2 Least Pending Requests First load balancer (" + size 391 + " backends)\n"; 392 } 393 394 397 public String getRaidb2Xml() 398 { 399 return "<" + DatabasesXmlTags.ELT_RAIDb_2_LeastPendingRequestsFirst + "/>"; 400 } 401 } | Popular Tags |