00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.controller.loadbalancer.raidb1;
00026
00027 import java.sql.SQLException;
00028 import java.util.ArrayList;
00029
00030 import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException;
00031 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException;
00032 import org.objectweb.cjdbc.common.i18n.Translate;
00033 import org.objectweb.cjdbc.common.sql.AbstractRequest;
00034 import org.objectweb.cjdbc.common.sql.SelectRequest;
00035 import org.objectweb.cjdbc.common.sql.StoredProcedure;
00036 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00037 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
00038 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache;
00039 import org.objectweb.cjdbc.controller.loadbalancer.policies.WaitForCompletionPolicy;
00040 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
00041 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 public class RAIDb1_RR extends RAIDb1
00054 {
00055
00056
00057
00058
00059
00060 private int index;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 public RAIDb1_RR(VirtualDatabase vdb,
00075 WaitForCompletionPolicy waitForCompletionPolicy) throws Exception
00076 {
00077 super(vdb, waitForCompletionPolicy);
00078 index = -1;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 public ControllerResultSet execReadRequest(SelectRequest request,
00093 MetadataCache metadataCache) throws SQLException
00094 {
00095 return executeRoundRobinRequest(request, true, "Request ", metadataCache);
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105 public ControllerResultSet execReadOnlyReadStoredProcedure(
00106 StoredProcedure proc, MetadataCache metadataCache) throws SQLException
00107 {
00108 return executeRoundRobinRequest(proc, false, "Stored procedure ",
00109 metadataCache);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 private ControllerResultSet executeRoundRobinRequest(AbstractRequest request,
00127 boolean isSelect, String errorMsgPrefix, MetadataCache metadataCache)
00128 throws SQLException
00129 {
00130
00131 try
00132 {
00133 vdb.acquireReadLockBackendLists();
00134 }
00135 catch (InterruptedException e)
00136 {
00137 String msg = Translate.get(
00138 "loadbalancer.backendlist.acquire.readlock.failed", e);
00139 logger.error(msg);
00140 throw new SQLException(msg);
00141 }
00142
00143 DatabaseBackend backend = null;
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 try
00154 {
00155 ArrayList backends = vdb.getBackends();
00156 int size = backends.size();
00157
00158 if (size == 0)
00159 throw new SQLException(Translate.get(
00160 "loadbalancer.execute.no.backend.available", request.getId()));
00161
00162
00163 int maxTries = size;
00164 synchronized (this)
00165 {
00166 do
00167 {
00168 index = (index + 1) % size;
00169 backend = (DatabaseBackend) backends.get(index);
00170 maxTries--;
00171 }
00172 while ((!backend.isReadEnabled() && maxTries >= 0));
00173 }
00174
00175 if (maxTries < 0)
00176 throw new NoMoreBackendException(Translate.get(
00177 "loadbalancer.execute.no.backend.enabled", request.getId()));
00178 }
00179 catch (RuntimeException e)
00180 {
00181 String msg = Translate.get("loadbalancer.execute.find.backend.failed",
00182 new String[]{request.getSQLShortForm(vdb.getSQLShortFormLength()),
00183 e.getMessage()});
00184 logger.error(msg, e);
00185 throw new SQLException(msg);
00186 }
00187 finally
00188 {
00189 vdb.releaseReadLockBackendLists();
00190 }
00191
00192 ControllerResultSet rs = null;
00193
00194 try
00195 {
00196 if (isSelect)
00197 rs = executeRequestOnBackend((SelectRequest) request, backend,
00198 metadataCache);
00199 else
00200 rs = executeStoredProcedureOnBackend((StoredProcedure) request,
00201 backend, metadataCache);
00202 }
00203 catch (UnreachableBackendException urbe)
00204 {
00205
00206 return executeRoundRobinRequest(request, isSelect, errorMsgPrefix,
00207 metadataCache);
00208 }
00209 catch (SQLException se)
00210 {
00211 String msg = Translate.get("loadbalancer.something.failed", new String[]{
00212 errorMsgPrefix, String.valueOf(request.getId()), se.getMessage()});
00213 if (logger.isInfoEnabled())
00214 logger.info(msg);
00215 throw se;
00216 }
00217 catch (RuntimeException e)
00218 {
00219 String msg = Translate.get("loadbalancer.something.failed.on",
00220 new String[]{errorMsgPrefix,
00221 request.getSQLShortForm(vdb.getSQLShortFormLength()),
00222 backend.getName(), e.getMessage()});
00223 logger.error(msg, e);
00224 throw new SQLException(msg);
00225 }
00226
00227 return rs;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 public String getInformation()
00240 {
00241
00242 int size = vdb.getBackends().size();
00243
00244 if (size == 0)
00245 return "RAIDb-1 Round-Robin Request load balancer: !!!Warning!!! No backend nodes found\n";
00246 else
00247 return "RAIDb-1 Round-Robin Request load balancer (" + size
00248 + " backends)\n";
00249 }
00250
00251
00252
00253
00254 public String getRaidb1Xml()
00255 {
00256 return "<" + DatabasesXmlTags.ELT_RAIDb_1_RoundRobin + "/>";
00257 }
00258
00259 }