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/Makefile.am b/lib/cpp/Makefile.am
index 84618f4..e0c69e9 100644
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -16,6 +16,7 @@
src/transport/TFileTransport.cpp \
src/transport/THttpClient.cpp \
src/transport/TSocket.cpp \
+ src/transport/TSocketPool.cpp \
src/transport/TServerSocket.cpp \
src/transport/TTransportUtils.cpp \
src/server/TSimpleServer.cpp \
@@ -64,6 +65,7 @@
src/transport/TServerTransport.h \
src/transport/THttpClient.h \
src/transport/TSocket.h \
+ src/transport/TSocketPool.h \
src/transport/TTransport.h \
src/transport/TTransportException.h \
src/transport/TTransportUtils.h
diff --git a/lib/cpp/src/transport/TSocket.h b/lib/cpp/src/transport/TSocket.h
index 30a09ac..b00f6ff 100644
--- a/lib/cpp/src/transport/TSocket.h
+++ b/lib/cpp/src/transport/TSocket.h
@@ -68,7 +68,7 @@
*
* @throws TTransportException If the socket could not connect
*/
- void open();
+ virtual void open();
/**
* Shuts down communications on the socket.
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
diff --git a/lib/cpp/src/transport/TSocketPool.h b/lib/cpp/src/transport/TSocketPool.h
new file mode 100644
index 0000000..0e30073
--- /dev/null
+++ b/lib/cpp/src/transport/TSocketPool.h
@@ -0,0 +1,100 @@
+// Copyright (c) 2006- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#ifndef _THRIFT_TRANSPORT_TSOCKETPOOL_H_
+#define _THRIFT_TRANSPORT_TSOCKETPOOL_H_ 1
+
+#include <vector>
+#include "TSocket.h"
+
+namespace facebook { namespace thrift { namespace transport {
+
+/**
+ * TCP Socket implementation of the TTransport interface.
+ *
+ * @author Mark Slee <mcslee@facebook.com>
+ */
+class TSocketPool : public TSocket {
+
+ public:
+ /**
+ * Socket pool constructor
+ *
+ * @param hosts list of host names
+ * @param ports list of port names
+ */
+ TSocketPool(const std::vector<std::string> &hosts,
+ const std::vector<int> &ports);
+
+ /**
+ * Socket pool constructor
+ *
+ * @param servers list of pairs of host name and port
+ */
+ TSocketPool(const std::vector<std::pair<std::string, int> > servers);
+
+ /**
+ * Destroyes the socket object, closing it if necessary.
+ */
+ virtual ~TSocketPool();
+
+ /**
+ * Sets how many times to keep retrying a host in the connect function.
+ */
+ void setNumRetries(int numRetries);
+
+ /**
+ * Sets how long to wait until retrying a host if it was marked down
+ */
+ void setRetryInterval(int retryInterval);
+
+ /**
+ * Sets how many times to keep retrying a host before marking it as down.
+ */
+ void setMaxConsecutiveFailures(int maxConsecutiveFailures);
+
+ /**
+ * Turns randomization in connect order on or off.
+ */
+ void setRandomize(bool randomize);
+
+ /**
+ * Whether to always try the last server.
+ */
+ void setAlwaysTryLast(bool alwaysTryLast);
+
+ /**
+ * Creates and opens the UNIX socket.
+ */
+ void open();
+
+ protected:
+
+ /** List of servers to connect to */
+ std::vector<std::pair<std::string, int> > servers_;
+
+ /** How many times to retry each host in connect */
+ int numRetries_;
+
+ /** Retry interval in seconds, how long to not try a host if it has been
+ * marked as down.
+ */
+ int retryInterval_;
+
+ /** Max consecutive failures before marking a host down. */
+ int maxConsecutiveFailures_;
+
+ /** Try hosts in order? or Randomized? */
+ bool randomize_;
+
+ /** Always try last host, even if marked down? */
+ bool alwaysTryLast_;
+};
+
+}}} // facebook::thrift::transport
+
+#endif // #ifndef _THRIFT_TRANSPORT_TSOCKETPOOL_H_
+
diff --git a/lib/cpp/src/transport/TTransportException.h b/lib/cpp/src/transport/TTransportException.h
index f865ecc..df27920 100644
--- a/lib/cpp/src/transport/TTransportException.h
+++ b/lib/cpp/src/transport/TTransportException.h
@@ -32,7 +32,8 @@
ALREADY_OPEN = 2,
TIMED_OUT = 3,
END_OF_FILE = 4,
- INTERRUPTED = 5
+ INTERRUPTED = 5,
+ BAD_ARGS = 6
};
TTransportException() :