Add multiserver generation to C++ Thrift
Summary: Autogen server that can encapsulates multiple server instances
Reviewed By: aditya
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664782 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index 6c5a0d6..2cff3fc 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -838,6 +838,9 @@
"}" << endl <<
endl;
+ // Multiserver
+ generate_service_multiserver(tservice);
+
// Generate the process subfunctions
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
generate_process_function(tservice, *f_iter);
@@ -845,6 +848,100 @@
}
/**
+ * Generates a multiserver, which is a single server that just takes a set
+ * of objects implementing the interface and calls them all, returning the
+ * value of the last one to be called.
+ *
+ * @param tservice The service to generate a multiserver for.
+ */
+void t_cpp_generator::generate_service_multiserver(t_service* tservice) {
+ // Generate the dispatch methods
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
+ string list_type = string("std::vector<boost::shared_ptr<") + service_name_ + "If> >";
+
+ // Generate the header portion
+ f_header_ <<
+ "class " << service_name_ << "MultiServer : " <<
+ "public " << service_name_ << "Server {" << endl <<
+ " public: " << endl;
+ indent_up();
+ f_header_ <<
+ indent() <<
+ service_name_ << "MultiServer(boost::shared_ptr<const facebook::thrift::protocol::TProtocol> protocol, " << list_type << "& servers) : " <<
+ service_name_ << "Server(protocol), _servers(servers) {}" << endl <<
+ indent() <<
+ service_name_ << "MultiServer(boost::shared_ptr<const facebook::thrift::protocol::TProtocol> iprot, boost::shared_ptr<const facebook::thrift::protocol::TProtocol> oprot, " << list_type << "& servers) : " <<
+ service_name_ << "Server(iprot, oprot), _servers(servers) {}" << endl <<
+ indent() << "virtual ~" << service_name_ << "MultiServer() {}" << endl;
+ indent_down();
+
+ // Protected data members
+ f_header_ <<
+ " protected:" << endl;
+ indent_up();
+ f_header_ <<
+ indent() << list_type << "& _servers;" << endl;
+ indent_down();
+
+ f_header_ <<
+ indent() << " public:" << endl;
+ indent_up();
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ t_struct* arglist = (*f_iter)->get_arglist();
+ const vector<t_field*>& args = arglist->get_members();
+ vector<t_field*>::const_iterator a_iter;
+
+ string call = string("_servers[i]->") + (*f_iter)->get_name() + "(";
+ bool first = true;
+ for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
+ if (first) {
+ first = false;
+ } else {
+ call += ", ";
+ }
+ call += (*a_iter)->get_name();
+ }
+ call += ")";
+
+ f_header_ <<
+ indent() << function_signature(*f_iter) << " {" << endl;
+ indent_up();
+ f_header_ <<
+ indent() << "uint32_t sz = _servers.size();" << endl <<
+ indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl;
+ if (!(*f_iter)->get_returntype()->is_void()) {
+ f_header_ <<
+ indent() << " if (i == sz - 1) {" << endl <<
+ indent() << " return " << call << ";" << endl <<
+ indent() << " } else {" << endl <<
+ indent() << " " << call << ";" << endl <<
+ indent() << " }" << endl;
+ } else {
+ f_header_ <<
+ indent() << " " << call << ";" << endl;
+ }
+
+ f_header_ <<
+ indent() << "}" << endl;
+
+ indent_down();
+ f_header_ <<
+ indent() << "}" << endl <<
+ endl;
+ }
+
+ indent_down();
+
+ f_header_ <<
+ indent() << "};" << endl <<
+ endl;
+}
+
+
+/**
* Generates a struct and helpers for a function.
*
* @param tfunction The function
diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h
index 7923852..fd208b6 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.h
+++ b/compiler/cpp/src/generate/t_cpp_generator.h
@@ -45,6 +45,7 @@
void generate_service_helpers (t_service* tservice);
void generate_service_client (t_service* tservice);
void generate_service_server (t_service* tservice);
+ void generate_service_multiserver(t_service* tservice);
void generate_process_function (t_service* tservice, t_function* tfunction);
void generate_function_helpers (t_function* tfunction);
diff --git a/lib/cpp/src/Thrift.h b/lib/cpp/src/Thrift.h
index 9254b56..410d20e 100644
--- a/lib/cpp/src/Thrift.h
+++ b/lib/cpp/src/Thrift.h
@@ -7,6 +7,7 @@
#include <map>
#include <list>
#include <set>
+#include <vector>
#include <exception>
namespace facebook { namespace thrift {