thrift: cpp tsocketpool support
summary: simple port of tsocketpool from php to cpp. missing a lot of functionality due to lack of apc support
review: slee


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665106 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TSocketPool.cpp b/lib/cpp/src/transport/TSocketPool.cpp
new file mode 100644
index 0000000..1450d1c
--- /dev/null
+++ b/lib/cpp/src/transport/TSocketPool.cpp
@@ -0,0 +1,101 @@
+// Copyright (c) 2007- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#include <algorithm>
+#include <iostream>
+
+#include "TSocketPool.h"
+
+namespace facebook { namespace thrift { namespace transport { 
+
+using namespace std;
+
+/**
+ * TSocketPool implementation.
+ *
+ * @author Jason Sobel <jsobel@facebook.com>
+ */
+
+TSocketPool::TSocketPool(const vector<string> &hosts,
+                         const vector<int> &ports) : TSocket(),
+  numRetries_(1),
+  retryInterval_(60),
+  maxConsecutiveFailures_(1),
+  randomize_(true),
+  alwaysTryLast_(true)
+{
+  if (hosts.size() != ports.size()) {
+    perror("TSocketPool::TSocketPool: hosts.size != ports.size");
+    throw TTransportException(TTransportException::BAD_ARGS);
+  }
+
+  for (unsigned int i = 0; i < hosts.size(); ++i) {
+    servers_.push_back(pair<string, int>(hosts[i], ports[i]));
+  }
+}
+
+TSocketPool::TSocketPool(const vector<pair<string, int> > servers) : TSocket(),
+  servers_(servers),
+  numRetries_(1),
+  retryInterval_(60),
+  maxConsecutiveFailures_(1),
+  randomize_(true),
+  alwaysTryLast_(true)
+{
+}
+
+TSocketPool::~TSocketPool() {
+  close();
+}
+
+void TSocketPool::setNumRetries(int numRetries) {
+  numRetries_ = numRetries;
+}
+
+void TSocketPool::setRetryInterval(int retryInterval) {
+  retryInterval_ = retryInterval;
+}
+
+
+void TSocketPool::setMaxConsecutiveFailures(int maxConsecutiveFailures) {
+  maxConsecutiveFailures_ = maxConsecutiveFailures;
+}
+
+void TSocketPool::setRandomize(bool randomize) {
+  randomize_ = randomize;
+}
+
+void TSocketPool::setAlwaysTryLast(bool alwaysTryLast) {
+  alwaysTryLast_ = alwaysTryLast;
+}
+
+/* TODO: without apc we ignore a lot of functionality from the php version */
+void TSocketPool::open() {
+  if (randomize_) {
+    std::random_shuffle(servers_.begin(), servers_.end());
+  }
+
+  for (unsigned int i = 0; i < servers_.size(); ++i) {
+    host_ = servers_[i].first;
+    port_ = servers_[i].second;
+
+    for (int j = 0; j < numRetries_; ++j) {
+      try {
+        TSocket::open();
+
+        // success
+        return;
+      } catch (TException e) {
+        // connection failed
+      }
+    }
+  }
+
+  perror("TSocketPool::open: all connections failed");
+  throw TTransportException(TTransportException::NOT_OPEN);
+}
+
+}}} // facebook::thrift::transport