Date: Monday, February 13, 2006 @ 15:42:09
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: include/Connection.hpp (1.55 -> 1.56) src/Connection.cpp (1.62
          -> 1.63)

Added calls to reconnect() using 2 macros
Added needed retrieveXXXResult


------------------------+
 include/Connection.hpp |   26 ++++-
 src/Connection.cpp     |  219 ++++++++++++++++++++++-------------------------
 2 files changed, 129 insertions(+), 116 deletions(-)


Index: carob/include/Connection.hpp
diff -u carob/include/Connection.hpp:1.55 carob/include/Connection.hpp:1.56
--- carob/include/Connection.hpp:1.55   Fri Feb 10 09:49:49 2006
+++ carob/include/Connection.hpp        Mon Feb 13 15:42:09 2006
@@ -52,8 +52,8 @@
 #define RetrieveExecuteUpdateResult             11
 #define RetrieveExecuteResult                   12
 //#define RetrieveExecuteUpdateWithKeysResult     13
-//#define RetrieveCommitResult                    14
-//#define RetrieveRollbackResult                  15
+#define RetrieveCommitResult                    14
+#define RetrieveRollbackResult                  15
 #define StatementExecute                        6
 #define Begin                                   20
 #define Commit                                  21
@@ -496,6 +496,22 @@
                           BackendException, ProtocolException, 
                           NotImplementedException, UnexpectedException);
   /**
+   * Check if the given commit has been successfully performed.
+   *
+   * @return transaction id if the commit has been successfully performed
+   */
+  int64_t             retrieveCommitResult() throw (SocketIOException,
+                          BackendException, ControllerException,
+                          ProtocolException, UnexpectedException);
+  /**
+   * Check if the given rollback has been successfully performed.
+   * 
+   * @return the transaction id if the rollback has been successfully performed
+   */
+  int64_t             retrieveRollbackResult() throw (SocketIOException,
+                          BackendException, ControllerException,
+                          ProtocolException, UnexpectedException);
+  /**
    * Checks if the given query already executed or not on the controller we are
    * currently connected to.
    *
@@ -542,9 +558,11 @@
    * controller chosen using the policy specified in the connection parameters
    * of this connection.
    * 
-   * @throw //TODO
+   * @throw NoMoreControllerException if no valid controller left
+   * @throw DriverException if an other error occured
    */
-  void reconnect() throw (NoMoreControllerException, UnexpectedException);
+  void                reconnect() throw (NoMoreControllerException,
+                            DriverException, UnexpectedException);
   /**
    * Forbids Connection creation that would lead to unexpected state.
    * A connection is either created, ie. connected to a controller or destroyed
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.62 carob/src/Connection.cpp:1.63
--- carob/src/Connection.cpp:1.62       Fri Feb 10 09:54:24 2006
+++ carob/src/Connection.cpp    Mon Feb 13 15:42:09 2006
@@ -36,6 +36,32 @@
 
 using namespace CarobNS;
 
+#define RECONNECT_RETRIES 10
+
+// The reconnection macro:
+// When a SocketIOException occurs between these to macros, sleep and try to
+// reconnect(). Sleeping time depends on the retry #. Only N retries are
+// performed
+#define FO_TRY_NTIMES(N) for (int foCnt=0; foCnt<N; foCnt++) { try {
+#define FO_CATCH_NTIMES break; /* if no exception, get out of the for */\
+} catch (SocketIOException sioe) { ::sleep(static_cast<int>(foCnt*0.5)); 
reconnect(); } }
+
+/* This gives:
+for (int foCnt=0; foCnt<N; foCnt++)
+{
+  try
+  {
+    ***CODE***
+    break; // if no exception, get out of the for
+  }
+  catch (SocketIOException sioe)
+  {
+    ::sleep(foCnt*0.5); // 0s the 1st and 2nd time, 1s the 3rd and 4th...
+    reconnect();
+  }
+}
+*/
+
 Connection::Connection(const ConnectionParameters& prms)
     throw (DriverException, ConnectionException, AuthenticationException, 
UnexpectedException) :
   driverSocketPtr(NULL),
@@ -391,9 +417,11 @@
 {
   if (mustBeginTransaction)
   {
-    sendCommand(*driverSocketPtr, Begin);
-    transactionId = receiveLongOrException();
-    mustBeginTransaction = false;
+    FO_TRY_NTIMES(RECONNECT_RETRIES)
+      sendCommand(*driverSocketPtr, Begin);
+      transactionId = receiveLongOrException();
+      mustBeginTransaction = false;
+    FO_CATCH_NTIMES
   }
 }
 
@@ -440,38 +468,20 @@
     mustBeginTransaction = true;
   }
   catch (SocketIOException e)
-  {
-    //TODO:
-    // Connection failed, try to reconnect and re-exec the commit
-    //try
-    //{
-      //reconnect();
-
-      //long acknowledgedTransactionId = retrieveCommitResult();
-      //if (acknowledgedTransactionId != transactionId)
-      //{
-        //throw new DriverSQLException(
-            //"Protocol error during commit rollback (acknowledge transaction 
ID = "
-                //+ acknowledgedTransactionId + ", expected transaction ID = "
-                //+ transactionId + ")");
-      //}
-
-      // The controller will automatically redo the commit if it was not done
-      // earlier so we can safely return here, this is a success.
-      //return;
-    //}
-    //catch (DriverSQLException e1)
-    //{
-    //  throw new DriverSQLException(
-    //      "Connection lost during commit of transaction '" + transactionId
-    //      + "' and automatic reconnect failed", e1);
-    //}
-    if (isWarningEnabled())
+  { // Connection failed, try to reconnect and re-exec the commit
+    reconnect();
+    int64_t acknowledgedTransactionId = retrieveCommitResult();
+    if (acknowledgedTransactionId != transactionId)
     {
-      logWarning(fctName, L"I/O Error occured around commit of transaction '"
-          + toWString(transactionId) + L"\n" + e.description());
+      throw (DriverException(
+          L"Error during commit failover (acknowledge transaction ID = "
+          + toWString(acknowledgedTransactionId)
+          + L", expected transaction ID = " + toWString(transactionId) + 
L")"));
     }
-    throw;
+
+    // The controller will automatically redo the commit if it was not done
+    // earlier so we can safely return here, this is a success.
+    return;
   }
 }
 
@@ -509,13 +519,19 @@
     mustBeginTransaction = true;
   }
   catch (SocketIOException e)
-  {
-    if (isWarningEnabled())
+  { // Connection failed, try to reconnect and re-exec the rollback
+    reconnect();
+    int64_t acknowledgedTransactionId = retrieveRollbackResult();
+    if (acknowledgedTransactionId != transactionId)
     {
-      logWarning(fctName, L"I/O Error occured around rollback of transaction '"
-          + toWString(transactionId) + L"\n" + e.description());
+      throw (DriverException(
+          L"Error during rollback failover (acknowledge transaction ID = "
+          + toWString(acknowledgedTransactionId)
+          + L", expected transaction ID = " + toWString(transactionId) + 
L")"));
     }
-    throw;
+    // The controller will automatically redo the rollback if it was not
+    // done earlier so we can safely return here, this is a success.
+    return;
   }
 }
 
@@ -554,14 +570,18 @@
   wstring fctName(L"Connection::PreparedStatementGetMetaData");
 
   LockScope ls(&connectionCS);
-//TODO: try/catch/reconnect
-  sendCommand(*driverSocketPtr, PreparedStatementGetMetaData);
-  *driverSocketPtr << sqlTemplate;
 
-  if (isDebugEnabled())
-    logDebug(fctName, L"Statement sent successfully");
+  FO_TRY_NTIMES(RECONNECT_RETRIES)
+    sendCommand(*driverSocketPtr, PreparedStatementGetMetaData);
+    *driverSocketPtr << sqlTemplate;
+  
+    if (isDebugEnabled())
+      logDebug(fctName, L"Statement sent successfully");
+  
+    return receiveResultSet();
+  FO_CATCH_NTIMES
 
-  return receiveResultSet();
+  return NULL; //avoid compiler warning
 }
 
 void Connection::setConnectionParametersOnRequest(Request &request)
@@ -570,7 +590,6 @@
   request.setIsReadOnly(readOnly);
 }
 
-//TODO: check that the code still sticks to java code
 DriverResultSet* Connection::statementExecuteQuery
     (RequestWithResultSetParameters& request)
     throw (SocketIOException, BackendException, ControllerException,
@@ -581,12 +600,12 @@
 
   LockScope ls(&connectionCS);
 
+  checkIfConnected();
+  beginTransactionIfNeeded();
+
   DriverResultSet* retVal = NULL;
 
-  try
-  {
-    checkIfConnected();
-    beginTransactionIfNeeded();
+  FO_TRY_NTIMES(RECONNECT_RETRIES)
     
     setConnectionParametersOnRequest(request);
     sendCommand(*driverSocketPtr, StatementExecuteQuery);
@@ -599,20 +618,14 @@
     switch(tag)
     {
       case TT_RESULTSET:
-        retVal = new DriverResultSet(this);
+          retVal = new DriverResultSet(this);
         break;
       //case TT_NULL_RESULTSET: nothing to do, just return NULL
       case TT_EXCEPTION:
         receiveException();
         break;
     }
-  }
-  catch (SocketIOException sioe)
-  {
-    //TODO: Reconnect and retry
-    throw;
-  }
-
+  FO_CATCH_NTIMES
   return retVal;
 }
 
@@ -624,43 +637,28 @@
 
   LockScope ls(&connectionCS);
 
+  checkIfConnected();
+  beginTransactionIfNeeded();
+
   int controllerResponse = -1;
-  
-  bool requestIdIsSet = false;
 
-  try
-  {
-    checkIfConnected();
-    beginTransactionIfNeeded();
+  FO_TRY_NTIMES(RECONNECT_RETRIES)
     setConnectionParametersOnRequest(request);
     sendCommand(*driverSocketPtr, StatementExecuteUpdate);
     writeRequestOnStream(request);
     request.setId(receiveLongOrException());
-    requestIdIsSet = true;
+  FO_CATCH_NTIMES
+  // At this point, the request id has been received, let's retrieve the
+  // update count
+  try
+  {
     controllerResponse = static_cast<int>(receiveIntOrException());
   }
   catch (SocketIOException sioe)
   {
-    wstring msg = L"Exception while executing write request: "
-                  + sioe.description()
-                  + L"). Connection probably lost";
-    if (isErrorEnabled())
-      logError(fctName, msg);
-
-    //TODO:
-    //reconnect()
-//    if (requestIdIsSet)
-//    { // Controller handled the query, check if it was executed
-//      int result = retrieveExecuteUpdateResult(request);
-//      if (result != -1)
-//        return result;
-//    }
-    // At this point the query failed before any controller succeeded in
-    // executing the query
-
-    throw SocketIOException(msg);
-    //in case exception is not catched
-    return -1;
+    FO_TRY_NTIMES(RECONNECT_RETRIES)
+    controllerResponse = retrieveExecuteUpdateResult(request);
+    FO_CATCH_NTIMES
   }
 
   return controllerResponse;
@@ -677,10 +675,7 @@
 
   std::list<ResultSetOrUpdateCount> results;
 
-  bool requestIdIsSet = false;
-
-  try
-  {
+  FO_TRY_NTIMES(RECONNECT_RETRIES)
     checkIfConnected();
     beginTransactionIfNeeded();
     setConnectionParametersOnRequest(request);
@@ -691,34 +686,17 @@
     if (isDebugEnabled())
       logDebug(fctName, L"Executing Statement.execute(" + (wstring)request + 
L")");
     request.setId(receiveLongOrException());
-    requestIdIsSet = true;
+  FO_CATCH_NTIMES
+  try
+  {
     results = fetchMultipleResultsFromStream();
   }
   catch (SocketIOException sioe)
   {
-    wstring msg = L"Exception while executing request: "
-                  + sioe.description()
-                  + L"). Connection probably lost";
-    if (isErrorEnabled())
-      logError(fctName, msg);
-    //TODO:
-//    reconnect();
-//    if (requestIdIsSet)
-//    { // Controller handled the query, check if it was executed
-//      List result = retrieveExecuteResult(request);
-//      if (result != null)
-//        return result;
-//    }
-//    // At this point the query failed before any controller succeeded in
-//    // executing the query
-//
-//    return statementExecute(request);
-  
-    throw SocketIOException(msg);
-    //in case exception is not catched
-    return results;
+    FO_TRY_NTIMES(RECONNECT_RETRIES)
+      results = retrieveExecuteResult(request);
+    FO_CATCH_NTIMES
   }
-
   return results;
 }
 
@@ -896,6 +874,22 @@
   return NULL;
 }
 
+int64_t Connection::retrieveCommitResult() throw (SocketIOException,
+    BackendException, ControllerException, ProtocolException,
+    UnexpectedException)
+{
+  sendCommand(*driverSocketPtr, RetrieveCommitResult);
+  return receiveLongOrException();
+}
+
+int64_t Connection::retrieveRollbackResult() throw (SocketIOException,
+    BackendException, ControllerException, ProtocolException,
+    UnexpectedException)
+{
+  sendCommand(*driverSocketPtr, RetrieveRollbackResult);
+  return receiveLongOrException();
+}
+
 DriverResultSet* Connection::retrieveExecuteQueryResult(const Request &request)
     throw (SocketIOException, BackendException, ControllerException,
     ProtocolException, UnexpectedException)
@@ -956,7 +950,8 @@
   return results;
 }
 
-void Connection::reconnect() throw (NoMoreControllerException, 
UnexpectedException)
+void Connection::reconnect() throw (NoMoreControllerException, DriverException,
+    UnexpectedException)
 {
   wstring fctName(L"Connection::reconnect");
   //Wait until other methods/Commands are done

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to