You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by dr...@apache.org on 2010/10/06 19:09:45 UTC

svn commit: r1005131 - /incubator/thrift/trunk/compiler/cpp/src/generate/t_cpp_generator.cc

Author: dreiss
Date: Wed Oct  6 17:09:45 2010
New Revision: 1005131

URL: http://svn.apache.org/viewvc?rev=1005131&view=rev
Log:
THRIFT-923. cpp: Add completion notification to async clients

Add a virtual function "completed__(bool)" to xxxCobClient that is
called by recv_xxx() after reception of a response (arg = true) or an
exception (arg = false). This allows the TAsyncClient to intercede at
that point, permitting, e.g., the load-balancing of persistent
connections that would otherwise remain bound to a single server.

A new "no_client_completion" flag inhibits generation of this mechanism.

Modified:
    incubator/thrift/trunk/compiler/cpp/src/generate/t_cpp_generator.cc

Modified: incubator/thrift/trunk/compiler/cpp/src/generate/t_cpp_generator.cc
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/compiler/cpp/src/generate/t_cpp_generator.cc?rev=1005131&r1=1005130&r2=1005131&view=diff
==============================================================================
--- incubator/thrift/trunk/compiler/cpp/src/generate/t_cpp_generator.cc (original)
+++ incubator/thrift/trunk/compiler/cpp/src/generate/t_cpp_generator.cc Wed Oct  6 17:09:45 2010
@@ -62,6 +62,9 @@ class t_cpp_generator : public t_oop_gen
     iter = parsed_options.find("cob_style");
     gen_cob_style_ = (iter != parsed_options.end());
 
+    iter = parsed_options.find("no_client_completion");
+    gen_no_client_completion_ = (iter != parsed_options.end());
+
     out_dir_base_ = "gen-cpp";
   }
 
@@ -238,6 +241,11 @@ class t_cpp_generator : public t_oop_gen
   bool gen_cob_style_;
 
   /**
+   * True if we should omit calls to completion__() in CobClient class.
+   */
+  bool gen_no_client_completion_;
+
+  /**
    * Strings for namespace, computed once up front then used directly
    */
 
@@ -1834,6 +1842,10 @@ void t_cpp_generator::generate_service_c
       indent() << "boost::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << endl <<
       indent() << "  return channel_;" << endl <<
       indent() << "}" << endl;
+    if (!gen_no_client_completion_) {
+      f_header_ <<
+        indent() << "virtual void completed__(bool success) {}" << endl;
+    }
   }
 
   vector<t_function*> functions = tservice->get_functions();
@@ -1991,27 +2003,49 @@ void t_cpp_generator::generate_service_c
           endl <<
           indent() << "int32_t rseqid = 0;" << endl <<
           indent() << "std::string fname;" << endl <<
-          indent() << "::apache::thrift::protocol::TMessageType mtype;" << endl <<
-          endl <<
+          indent() << "::apache::thrift::protocol::TMessageType mtype;" << endl;
+        if (style == "Cob" && !gen_no_client_completion_) {
+          f_service_ <<
+            indent() << "bool completed = false;" << endl << endl <<
+            indent() << "try {";
+          indent_up();
+        }
+        f_service_ << endl <<
           indent() << "iprot_->readMessageBegin(fname, mtype, rseqid);" << endl <<
           indent() << "if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {" << endl <<
           indent() << "  ::apache::thrift::TApplicationException x;" << endl <<
           indent() << "  x.read(iprot_);" << endl <<
           indent() << "  iprot_->readMessageEnd();" << endl <<
-          indent() << "  iprot_->getTransport()->readEnd();" << endl <<
+          indent() << "  iprot_->getTransport()->readEnd();" << endl;
+        if (style == "Cob" && !gen_no_client_completion_) {
+          f_service_ <<
+            indent() << "  completed = true;" << endl <<
+            indent() << "  completed__(true);" << endl;
+        }
+        f_service_ <<
           indent() << "  throw x;" << endl <<
           indent() << "}" << endl <<
           indent() << "if (mtype != ::apache::thrift::protocol::T_REPLY) {" << endl <<
           indent() << "  iprot_->skip(::apache::thrift::protocol::T_STRUCT);" << endl <<
           indent() << "  iprot_->readMessageEnd();" << endl <<
-          indent() << "  iprot_->getTransport()->readEnd();" << endl <<
-          indent() << "  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::INVALID_MESSAGE_TYPE);" << endl <<
+          indent() << "  iprot_->getTransport()->readEnd();" << endl;
+        if (style == "Cob" && !gen_no_client_completion_) {
+          f_service_ <<
+            indent() << "  completed = true;" << endl <<
+            indent() << "  completed__(false);" << endl;
+        }
+        f_service_ <<
           indent() << "}" << endl <<
           indent() << "if (fname.compare(\"" << (*f_iter)->get_name() << "\") != 0) {" << endl <<
           indent() << "  iprot_->skip(::apache::thrift::protocol::T_STRUCT);" << endl <<
           indent() << "  iprot_->readMessageEnd();" << endl <<
-          indent() << "  iprot_->getTransport()->readEnd();" << endl <<
-          indent() << "  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::WRONG_METHOD_NAME);" << endl <<
+          indent() << "  iprot_->getTransport()->readEnd();" << endl;
+        if (style == "Cob" && !gen_no_client_completion_) {
+          f_service_ <<
+            indent() << "  completed = true;" << endl <<
+            indent() << "  completed__(false);" << endl;
+        }
+        f_service_ <<
           indent() << "}" << endl;
 
         if (!(*f_iter)->get_returntype()->is_void() &&
@@ -2040,12 +2074,24 @@ void t_cpp_generator::generate_service_c
           if (is_complex_type((*f_iter)->get_returntype())) {
             f_service_ <<
               indent() << "if (result.__isset.success) {" << endl <<
-              indent() << "  // _return pointer has now been filled" << endl <<
+              indent() << "  // _return pointer has now been filled" << endl;
+            if (style == "Cob" && !gen_no_client_completion_) {
+              f_service_ <<
+                indent() << "  completed = true;" << endl <<
+                indent() << "  completed__(true);" << endl;
+            }
+            f_service_ <<
               indent() << "  return;" << endl <<
               indent() << "}" << endl;
           } else {
             f_service_ <<
-              indent() << "if (result.__isset.success) {" << endl <<
+              indent() << "if (result.__isset.success) {" << endl;
+            if (style == "Cob" && !gen_no_client_completion_) {
+              f_service_ <<
+                indent() << "  completed = true;" << endl <<
+                indent() << "  completed__(true);" << endl;
+            }
+            f_service_ <<
               indent() << "  return _return;" << endl <<
               indent() << "}" << endl;
           }
@@ -2056,20 +2102,45 @@ void t_cpp_generator::generate_service_c
         vector<t_field*>::const_iterator x_iter;
         for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
           f_service_ <<
-            indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl <<
+            indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl;
+          if (style == "Cob" && !gen_no_client_completion_) {
+            f_service_ <<
+              indent() << "  completed = true;" << endl <<
+              indent() << "  completed__(true);" << endl;
+          }
+          f_service_  <<
             indent() << "  throw result." << (*x_iter)->get_name() << ";" << endl <<
             indent() << "}" << endl;
         }
 
         // We only get here if we are a void function
         if ((*f_iter)->get_returntype()->is_void()) {
+          if (style == "Cob" && !gen_no_client_completion_) {
+            f_service_ <<
+              indent() << "completed = true;" << endl <<
+              indent() << "completed__(true);" << endl;
+          }
           indent(f_service_) <<
             "return;" << endl;
         } else {
+          if (style == "Cob" && !gen_no_client_completion_) {
+            f_service_ <<
+              indent() << "completed = true;" << endl <<
+              indent() << "completed__(true);" << endl;
+          }
           f_service_ <<
             indent() << "throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, \"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
         }
-
+        if (style == "Cob" && !gen_no_client_completion_) {
+          indent_down();
+          f_service_ <<
+            indent() << "} catch (...) {" << endl <<
+            indent() << "  if (!completed) {" << endl <<
+            indent() << "    completed__(false);" << endl <<
+            indent() << "  }" << endl <<
+            indent() << "  throw;" << endl <<
+            indent() << "}" << endl;
+        }
         // Close function
         scope_down(f_service_);
         f_service_ << endl;