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 53 public class RAIDb2_RR extends RAIDb2 54 { 55 59 60 private int index; 62 65 66 76 public RAIDb2_RR(VirtualDatabase vdb, 77 WaitForCompletionPolicy waitForCompletionPolicy, 78 CreateTablePolicy createTablePolicy) throws Exception 79 { 80 super(vdb, waitForCompletionPolicy, createTablePolicy); 81 index = -1; 82 } 83 84 87 88 100 public ControllerResultSet execReadRequest(SelectRequest request, 101 MetadataCache metadataCache) throws SQLException 102 { 103 try 105 { 106 vdb.acquireReadLockBackendLists(); 107 } 108 catch (InterruptedException e) 109 { 110 String msg = Translate.get( 111 "loadbalancer.backendlist.acquire.readlock.failed", e); 112 logger.error(msg); 113 throw new SQLException (msg); 114 } 115 116 DatabaseBackend backend = null; 118 try 121 { 122 ArrayList backends = vdb.getBackends(); 123 int size = backends.size(); 124 125 if (size == 0) 126 throw new SQLException (Translate.get( 127 "loadbalancer.execute.no.backend.available", request.getId())); 128 129 int maxTries = size; 131 int enabledBackends = 0; 132 ArrayList tables = request.getFrom(); 133 134 synchronized (this) 135 { 136 do 137 { 138 index = (index + 1) % size; 139 backend = (DatabaseBackend) backends.get(index); 140 if (backend.isReadEnabled()) 141 { 142 enabledBackends++; 143 if (backend.hasTables(tables)) 144 break; 145 } 146 maxTries--; 147 } 148 while (maxTries >= 0); 149 } 150 151 if (maxTries < 0) 152 { if (enabledBackends == 0) 154 throw new NoMoreBackendException(Translate.get( 155 "loadbalancer.execute.no.backend.enabled", request.getId())); 156 else 157 throw new SQLException (Translate.get( 158 "loadbalancer.backend.no.required.tables", tables.toString())); 159 } 160 } 161 catch (RuntimeException e) 162 { 163 String msg = Translate.get("loadbalancer.request.failed.on.backend", 164 new String []{request.getSQLShortForm(vdb.getSQLShortFormLength()), 165 backend.getName(), e.getMessage()}); 166 logger.error(msg, e); 167 throw new SQLException (msg); 168 } 169 finally 170 { 171 vdb.releaseReadLockBackendLists(); 172 } 173 174 ControllerResultSet rs = null; 176 try 177 { 178 rs = executeRequestOnBackend(request, backend, metadataCache); 179 } 180 catch (UnreachableBackendException se) 181 { 182 return execReadRequest(request, metadataCache); 184 } 185 catch (SQLException se) 186 { 187 String msg = Translate.get("loadbalancer.request.failed", new String []{ 188 String.valueOf(request.getId()), se.getMessage()}); 189 if (logger.isInfoEnabled()) 190 logger.info(msg); 191 throw new SQLException (msg); 192 } 193 catch (RuntimeException e) 194 { 195 String msg = Translate.get("loadbalancer.request.failed.on.backend", 196 new String []{request.getSQLShortForm(vdb.getSQLShortFormLength()), 197 backend.getName(), e.getMessage()}); 198 logger.error(msg, e); 199 throw new SQLException (msg); 200 } 201 202 return rs; 203 } 204 205 213 public ControllerResultSet execReadOnlyReadStoredProcedure( 214 StoredProcedure proc, MetadataCache metadataCache) throws SQLException 215 { 216 try 218 { 219 vdb.acquireReadLockBackendLists(); 220 } 221 catch (InterruptedException e) 222 { 223 String msg = Translate.get( 224 "loadbalancer.backendlist.acquire.readlock.failed", e); 225 logger.error(msg); 226 throw new SQLException (msg); 227 } 228 229 DatabaseBackend backend = null; 231 try 234 { 235 DatabaseBackend failedBackend = null; 236 SQLException failedException = null; 237 ControllerResultSet rs = null; 238 do 239 { 240 ArrayList backends = vdb.getBackends(); 241 int size = backends.size(); 242 243 if (size == 0) 244 throw new SQLException (Translate.get( 245 "loadbalancer.execute.no.backend.available", proc.getId())); 246 247 int maxTries = size; 249 int enabledBackends = 0; 250 251 synchronized (this) 252 { 253 do 254 { 255 index = (index + 1) % size; 256 backend = (DatabaseBackend) backends.get(index); 257 if (backend.isReadEnabled()) 258 { 259 enabledBackends++; 260 if ((backend != failedBackend) 261 && backend.hasStoredProcedure(proc.getProcedureName())) 262 break; 263 } 264 maxTries--; 265 } 266 while (maxTries >= 0); 267 } 268 269 if (maxTries < 0) 270 { if (enabledBackends == 0) 272 throw new SQLException (Translate.get( 273 "loadbalancer.execute.no.backend.enabled", proc.getId())); 274 else if (failedBackend == null) 275 throw new SQLException (Translate.get( 276 "loadbalancer.backend.no.required.storedprocedure", proc 277 .getProcedureName())); 278 else 279 throw failedException; 281 } 282 283 boolean toDisable = false; 285 try 286 { 287 rs = executeStoredProcedureOnBackend(proc, backend, metadataCache); 288 if (failedBackend != null) 289 { if (logger.isWarnEnabled()) 291 logger.warn(Translate.get("loadbalancer.storedprocedure.status", 292 new String []{String.valueOf(proc.getId()), backend.getName(), 293 failedBackend.getName()})); 294 toDisable = true; 295 } 296 } 297 catch (UnreachableBackendException se) 298 { 299 continue; 301 } 302 catch (SQLException se) 303 { 304 if (failedBackend != null) 305 { String msg = Translate.get( 307 "loadbalancer.storedprocedure.failed.twice", new String []{ 308 String.valueOf(proc.getId()), se.getMessage()}); 309 if (logger.isInfoEnabled()) 310 logger.info(msg); 311 throw new SQLException (msg); 312 } 313 else 314 { failedBackend = backend; 316 failedException = se; 317 if (logger.isInfoEnabled()) 318 logger.info(Translate.get( 319 "loadbalancer.storedprocedure.failed.on.backend", 320 new String []{ 321 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 322 backend.getName(), se.getMessage()})); 323 continue; 324 } 325 } 326 327 if (toDisable) 328 { try 331 { 332 if (logger.isWarnEnabled()) 333 logger.warn(Translate.get("loadbalancer.backend.disabling", 334 failedBackend.getName())); 335 disableBackend(failedBackend); 336 } 337 catch (SQLException ignore) 338 { 339 } 340 finally 341 { 342 failedBackend = null; } 344 } 345 } 346 while (failedBackend != null); 347 return rs; 348 } 349 catch (RuntimeException e) 350 { 351 String msg = Translate.get( 352 "loadbalancer.storedprocedure.failed.on.backend", new String []{ 353 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 354 backend.getName(), e.getMessage()}); 355 logger.fatal(msg, e); 356 throw new SQLException (msg); 357 } 358 finally 359 { 360 vdb.releaseReadLockBackendLists(); 361 } 362 } 363 364 367 368 373 public String getInformation() 374 { 375 int size = vdb.getBackends().size(); 377 378 if (size == 0) 379 return "RAIDb-2 Round-Robin Request load balancer: !!!Warning!!! No backend nodes found\n"; 380 else 381 return "RAIDb-2 Round-Robin Request load balancer (" + size 382 + " backends)\n"; 383 } 384 385 388 public String getRaidb2Xml() 389 { 390 return "<" + DatabasesXmlTags.ELT_RAIDb_2_RoundRobin + "/>"; 391 } 392 } | Popular Tags |