1 22 23 package org.continuent.sequoia.controller.loadbalancer.raidb1; 24 25 import java.sql.SQLException ; 26 import java.util.ArrayList ; 27 28 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 29 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 30 import org.continuent.sequoia.common.i18n.Translate; 31 import org.continuent.sequoia.common.xml.DatabasesXmlTags; 32 import org.continuent.sequoia.controller.backend.DatabaseBackend; 33 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 34 import org.continuent.sequoia.controller.backend.result.ExecuteResult; 35 import org.continuent.sequoia.controller.cache.metadata.MetadataCache; 36 import org.continuent.sequoia.controller.loadbalancer.policies.WaitForCompletionPolicy; 37 import org.continuent.sequoia.controller.requests.AbstractRequest; 38 import org.continuent.sequoia.controller.requests.SelectRequest; 39 import org.continuent.sequoia.controller.requests.StoredProcedure; 40 import org.continuent.sequoia.controller.virtualdatabase.VirtualDatabase; 41 42 52 public class RAIDb1_RR extends RAIDb1 53 { 54 58 59 private int index; 61 64 65 73 public RAIDb1_RR(VirtualDatabase vdb, 74 WaitForCompletionPolicy waitForCompletionPolicy) throws Exception 75 { 76 super(vdb, waitForCompletionPolicy); 77 index = -1; 78 } 79 80 83 84 91 public ControllerResultSet execSingleBackendReadRequest( 92 SelectRequest request, MetadataCache metadataCache) throws SQLException 93 { 94 return (ControllerResultSet) executeRoundRobinRequest(request, 95 STATEMENT_EXECUTE_QUERY, "Request ", metadataCache); 96 } 97 98 105 public ControllerResultSet readOnlyCallableStatementExecuteQuery( 106 StoredProcedure proc, MetadataCache metadataCache) throws SQLException 107 { 108 return (ControllerResultSet) executeRoundRobinRequest(proc, 109 CALLABLE_STATEMENT_EXECUTE_QUERY, "Stored procedure ", metadataCache); 110 } 111 112 120 public ExecuteResult readOnlyCallableStatementExecute(StoredProcedure proc, 121 MetadataCache metadataCache) throws SQLException 122 { 123 return (ExecuteResult) executeRoundRobinRequest(proc, 124 CALLABLE_STATEMENT_EXECUTE, "Stored procedure ", metadataCache); 125 } 126 127 141 private Object executeRoundRobinRequest(AbstractRequest request, 142 int callType, String errorMsgPrefix, MetadataCache metadataCache) 143 throws SQLException 144 { 145 try 147 { 148 vdb.acquireReadLockBackendLists(); 149 } 150 catch (InterruptedException e) 151 { 152 String msg = Translate.get( 153 "loadbalancer.backendlist.acquire.readlock.failed", e); 154 logger.error(msg); 155 throw new SQLException (msg); 156 } 157 158 DatabaseBackend backend = null; 160 161 try 164 { 165 ArrayList backends = vdb.getBackends(); 166 int size = backends.size(); 167 168 if (size == 0) 169 throw new NoMoreBackendException(Translate.get( 170 "loadbalancer.execute.no.backend.available", request.getId())); 171 172 int maxTries = size; 174 synchronized (this) 175 { 176 do 177 { 178 index = (index + 1) % size; 179 backend = (DatabaseBackend) backends.get(index); 180 maxTries--; 181 } 182 while ((!backend.isReadEnabled() && maxTries >= 0)); 183 } 184 185 if (maxTries < 0) 186 throw new NoMoreBackendException(Translate.get( 187 "loadbalancer.execute.no.backend.enabled", request.getId())); 188 } 189 catch (RuntimeException e) 190 { 191 String msg = Translate.get("loadbalancer.execute.find.backend.failed", 192 new String []{request.getSqlShortForm(vdb.getSqlShortFormLength()), 193 e.getMessage()}); 194 logger.error(msg, e); 195 throw new SQLException (msg); 196 } 197 finally 198 { 199 vdb.releaseReadLockBackendLists(); 200 } 201 202 try 204 { 205 switch (callType) 206 { 207 case STATEMENT_EXECUTE_QUERY : 208 return executeRequestOnBackend((SelectRequest) request, backend, 209 metadataCache); 210 case CALLABLE_STATEMENT_EXECUTE_QUERY : 211 return executeStoredProcedureOnBackend((StoredProcedure) request, 212 true, backend, metadataCache); 213 case CALLABLE_STATEMENT_EXECUTE : 214 return executeStoredProcedureOnBackend((StoredProcedure) request, 215 false, backend, metadataCache); 216 default : 217 throw new RuntimeException ("Unhandled call type " + callType 218 + " in executeRoundRobin"); 219 } 220 } 221 catch (UnreachableBackendException urbe) 222 { 223 return executeRoundRobinRequest(request, callType, errorMsgPrefix, 225 metadataCache); 226 } 227 catch (SQLException se) 228 { 229 String msg = Translate.get("loadbalancer.something.failed", new String []{ 230 errorMsgPrefix, String.valueOf(request.getId()), se.getMessage()}); 231 if (logger.isInfoEnabled()) 232 logger.info(msg); 233 throw se; 234 } 235 catch (RuntimeException e) 236 { 237 String msg = Translate.get("loadbalancer.something.failed.on", 238 new String []{errorMsgPrefix, 239 request.getSqlShortForm(vdb.getSqlShortFormLength()), 240 backend.getName(), e.getMessage()}); 241 logger.error(msg, e); 242 throw new SQLException (msg); 243 } 244 } 245 246 249 250 255 public String getInformation() 256 { 257 int size = vdb.getBackends().size(); 259 260 if (size == 0) 261 return "RAIDb-1 Round-Robin Request load balancer: !!!Warning!!! No backend nodes found\n"; 262 else 263 return "RAIDb-1 Round-Robin Request load balancer (" + size 264 + " backends)\n"; 265 } 266 267 270 public String getRaidb1Xml() 271 { 272 return "<" + DatabasesXmlTags.ELT_RAIDb_1_RoundRobin + "/>"; 273 } 274 275 } | Popular Tags |