summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/cluster/Cpg.cpp
diff options
context:
space:
mode:
authorMichael Goulish <mgoulish@apache.org>2009-12-11 15:29:00 +0000
committerMichael Goulish <mgoulish@apache.org>2009-12-11 15:29:00 +0000
commitae56849be17361e90a7cd7074fc31674df2d724a (patch)
tree4e906993e2ad8f1a1ae53f726ef35b4f7202bb3b /cpp/src/qpid/cluster/Cpg.cpp
parent2e43ee118c7a7e1076bcba10afa3ecaa903cb537 (diff)
downloadqpid-python-ae56849be17361e90a7cd7074fc31674df2d724a.tar.gz
Add retry capability to several cpg calls.
First retry is immediate, next one after 10 usec, then 100 usec, etc ... for 5 retries. Retry pause maxes out at 0.1 second. Then give up and report error. The lack of retry on one of these calls must have been responsible for several hard-to-reproduce failures seen over the last month or so. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@889657 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/cluster/Cpg.cpp')
-rw-r--r--cpp/src/qpid/cluster/Cpg.cpp35
1 files changed, 32 insertions, 3 deletions
diff --git a/cpp/src/qpid/cluster/Cpg.cpp b/cpp/src/qpid/cluster/Cpg.cpp
index 5efa91f11c..3ae0c970c7 100644
--- a/cpp/src/qpid/cluster/Cpg.cpp
+++ b/cpp/src/qpid/cluster/Cpg.cpp
@@ -39,6 +39,8 @@ namespace cluster {
using namespace std;
+
+
Cpg* Cpg::cpgFromHandle(cpg_handle_t handle) {
void* cpg=0;
CPG_CHECK(cpg_context_get(handle, &cpg), "Cannot get CPG instance.");
@@ -46,6 +48,28 @@ Cpg* Cpg::cpgFromHandle(cpg_handle_t handle) {
return reinterpret_cast<Cpg*>(cpg);
}
+// Applies the same retry-logic to all cpg calls that need it.
+void Cpg::callCpg ( CpgOp & c ) {
+ cpg_error_t result;
+ unsigned int snooze = 10;
+ for ( unsigned int nth_try = 0; nth_try < cpgRetries; ++ nth_try ) {
+ if ( CPG_OK == (result = c.op(handle, & group))) {
+ QPID_LOG(info, c.opName << " successful.");
+ break;
+ }
+ else if ( result == CPG_ERR_TRY_AGAIN ) {
+ QPID_LOG(info, "Retrying " << c.opName );
+ sys::usleep ( snooze );
+ snooze *= 10;
+ snooze = (snooze <= maxCpgRetrySleep) ? snooze : maxCpgRetrySleep;
+ }
+ else break; // Don't retry unless CPG tells us to.
+ }
+
+ if ( result != CPG_OK )
+ CPG_CHECK(result, c.msg(group));
+}
+
// Global callback functions.
void Cpg::globalDeliver (
cpg_handle_t handle,
@@ -129,11 +153,11 @@ Cpg::~Cpg() {
void Cpg::join(const std::string& name) {
group = name;
- CPG_CHECK(cpg_join(handle, &group), cantJoinMsg(group));
+ callCpg ( cpgJoinOp );
}
void Cpg::leave() {
- CPG_CHECK(cpg_leave(handle, &group), cantLeaveMsg(group));
+ callCpg ( cpgLeaveOp );
}
@@ -158,7 +182,8 @@ void Cpg::shutdown() {
if (!isShutdown) {
QPID_LOG(debug,"Shutting down CPG");
isShutdown=true;
- CPG_CHECK(cpg_finalize(handle), "Error in shutdown of CPG");
+
+ callCpg ( cpgFinalizeOp );
}
}
@@ -201,6 +226,10 @@ std::string Cpg::cantJoinMsg(const Name& group) {
return "Cannot join CPG group "+group.str();
}
+std::string Cpg::cantFinalizeMsg(const Name& group) {
+ return "Cannot finalize CPG group "+group.str();
+}
+
std::string Cpg::cantLeaveMsg(const Name& group) {
return "Cannot leave CPG group "+group.str();
}