merge changes for 0.6 rc2
authorT Jake Luciani <jake@apache.org>
Mon, 31 Jan 2011 01:57:14 +0000 (01:57 +0000)
committerT Jake Luciani <jake@apache.org>
Mon, 31 Jan 2011 01:57:14 +0000 (01:57 +0000)
git-svn-id: https://svn.apache.org/repos/asf/thrift/branches/0.6.x@1065464 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
compiler/cpp/src/generate/t_js_generator.cc
lib/csharp/src/Transport/TFramedTransport.cs
lib/java/src/org/apache/thrift/async/TAsyncClientManager.java
lib/js/thrift.js
lib/nodejs/lib/thrift/thrift.js
test/csharp/ThriftTest/TestClient.cs
test/csharp/ThriftTest/TestServer.cs

diff --git a/CHANGES b/CHANGES
index 0609ca2..1f92670 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,7 @@ THRIFT-975    C glib               lib/c_glib/README is missing => breaks make d
 THRIFT-1003   C glib               Polishing c_glib code (Anatol Pomozov)
 THRIFT-582    C glib               C implementation of Thrift (Anatol Pomozov)
 THRIFT-992    C#                   Naming convention in C# constructor is not consistent with other fields causes compile errors (Roger Meier)
+THRIFT-904    C#                  Disable nagle and linger
 THRIFT-977    C++                  Hex Conversion Bug in C++ TJSONProtocol (Aravind Narayanan)
 THRIFT-922    C++                  Templatized [de]serialization code for C++ (David Reiss)
 THRIFT-923    C++                  Event-driven client and server support for C++ (David Reiss)
@@ -48,10 +49,14 @@ THRIFT-946    Java                 Augment FieldValueMetaData so it differentiat
 THRIFT-949    Java                 Modify the TEnum interface so it defines a method similar to findByValue (Mathias Herberts)
 THRIFT-960    Java                 add TestServer, TestNonblockingServer and TestClient again (Roger Meier)
 THRIFT-969    Java                 Java Tutorial broken, move CalculatorHandler to a separate file (Roger Meier)
+THRIFT-1051   Java                Fix compiler issue for java 1.5
 THRIFT-807    JavaScript           JavaScript: Initialization of Base Types with 0 instead of null (Roger Meier)
 THRIFT-913    JavaScript           Test Case for Url encoded strings + simple enhancement to lib/js/test/RunTestServer.sh (Roger Meier)
 THRIFT-961    JavaScript
-THRIFT-1033   JavaScript           Node.js support
+THRIFT-1033   JavaScript           Node.js support (Wade Simmons)
+THRIFT-1042   JavaScript           Node.js Fix TApplicationException.read Patch (Wade Simmons)
+THRIFT-1043   JavaScript          Node.js Fix how the length of a map is calculated
+THRIFT-1044   JavaScript          Fix JavaScript inheritance Patch (Wade Simmons)
 THRIFT-71     Misc                 Debian packaging for thrift (Roger Meier)
 THRIFT-1020   OCaml                OCaml compiler generates invalid OCaml (Richard Low)
 THRIFT-347    PHP                  PHP TSocket Timeout Issues (Tyler Hobbs)
index 4aa6811..a654fc9 100644 (file)
@@ -157,6 +157,7 @@ class t_js_generator : public t_oop_generator {
    */
 
   std::string js_includes();
+  std::string render_includes();
   std::string declare_field(t_field* tfield, bool init=false, bool obj=false);
   std::string function_signature(t_function* tfunction, std::string prefix="", bool include_callback=false);
   std::string argument_list(t_struct* tstruct);
@@ -191,11 +192,15 @@ class t_js_generator : public t_oop_generator {
       return pieces;
   }
 
-  std::string js_type_namespace(t_program* p) {
+  std::string js_type_namespace(t_type* ttype) {
+    t_program* program = ttype->get_program();
     if (gen_node_) {
+      if (program != NULL && program != program_) {
+        return program->get_name() + "_ttypes.";
+      }
       return "ttypes.";
     }
-    return js_namespace(p);
+    return js_namespace(program);
   }
 
   std::string js_export_namespace(t_program* p) {
@@ -286,6 +291,26 @@ string t_js_generator::js_includes() {
   return inc;
 }
 
+/**
+ * Renders all the imports necessary for including another Thrift program
+ */
+string t_js_generator::render_includes() {
+  if (gen_node_) {
+    const vector<t_program*>& includes = program_->get_includes();
+    string result = "";
+    for (size_t i = 0; i < includes.size(); ++i) {
+      result += "var " + includes[i]->get_name() + "_ttypes = require('./" + includes[i]->get_name() + "_types')\n";
+    }
+    if (includes.size() > 0) {
+      result += "\n";
+    }
+    return result;
+  }
+  string inc;
+
+  return inc;
+}
+
 /**
  * Close up (or down) some filez.
  */
@@ -311,7 +336,7 @@ void t_js_generator::generate_typedef(t_typedef* ttypedef) {
  * @param tenum The enumeration
  */
 void t_js_generator::generate_enum(t_enum* tenum) {
-  f_types_ << js_type_namespace(tenum->get_program())<<tenum->get_name()<<" = { "<<endl;
+  f_types_ << js_type_namespace(tenum)<<tenum->get_name()<<" = { "<<endl;
 
   vector<t_enum_value*> constants = tenum->get_constants();
   vector<t_enum_value*>::iterator c_iter;
@@ -334,7 +359,7 @@ void t_js_generator::generate_const(t_const* tconst) {
   string name = tconst->get_name();
   t_const_value* value = tconst->get_value();
 
-  f_types_ << js_type_namespace(program_)  << name << " = ";
+  f_types_ << js_type_namespace(type)  << name << " = ";
   f_types_ << render_const_value(type, value) << endl;
 }
 
@@ -376,7 +401,7 @@ string t_js_generator::render_const_value(t_type* type, t_const_value* value) {
   } else if (type->is_enum()) {
     out << value->get_integer();
   } else if (type->is_struct() || type->is_xception()) {
-    out << "new " << js_type_namespace(type->get_program()) << type->get_name() << "({" << endl;
+    out << "new " << js_type_namespace(type) << type->get_name() << "({" << endl;
     indent_up();
     const vector<t_field*>& fields = ((t_struct*)type)->get_members();
     vector<t_field*>::const_iterator f_iter;
@@ -541,19 +566,12 @@ void t_js_generator::generate_js_struct_definition(ofstream& out,
   out << "}\n";
 
   if (is_exception) {
-      if (gen_node_) {
-          out << "require('util').inherits(" <<
-              js_namespace(tstruct->get_program()) <<
-              tstruct->get_name() << ", Thrift.TException)" << endl;
-      } else {
-          out << "for (var property in Thrift.TException)"<<endl<<
-              js_namespace(tstruct->get_program())<<tstruct->get_name()<<"[property] = Thrift.TException[property]"<<endl;
-      }
-  }
-
-  if (!gen_node_) {
-      //init prototype
-      out << js_namespace(tstruct->get_program())<<tstruct->get_name() <<".prototype = {}\n";
+    out << "Thrift.inherits(" <<
+        js_namespace(tstruct->get_program()) <<
+        tstruct->get_name() << ", Thrift.TException)" << endl;
+  } else {
+    //init prototype
+    out << js_namespace(tstruct->get_program())<<tstruct->get_name() <<".prototype = {}\n";
   }
 
 
@@ -696,11 +714,23 @@ void t_js_generator::generate_service(t_service* tservice) {
 
     f_service_ <<
       autogen_comment() <<
-      js_includes() << endl;
+      js_includes() << endl <<
+      render_includes() << endl;
 
     if (gen_node_) {
-      f_service_ <<
-        "var ttypes = require('./" + program_->get_name() + "_types.js');" << endl;
+        if (tservice->get_extends() != NULL) {
+          f_service_ <<
+            "var " << tservice->get_extends()->get_name() <<
+            " = require('./" << tservice->get_extends()->get_name() << "')" << endl <<
+            "var " << tservice->get_extends()->get_name() << "Client = " <<
+            tservice->get_extends()->get_name() << ".Client" << endl;
+
+        }
+
+        if (gen_node_) {
+          f_service_ <<
+            "var ttypes = require('./" + program_->get_name() + "_types');" << endl;
+        }
     }
 
     generate_service_helpers(tservice);
@@ -935,17 +965,15 @@ void t_js_generator::generate_service_client(t_service* tservice) {
 
 
   if (tservice->get_extends() != NULL) {
-      extends = tservice->get_extends()->get_name();
-
-      f_service_ << "for (var property in "<<extends<<"Client)"<<endl<<
-          js_namespace(tservice->get_program()) << service_name_<<"Client[property] = "<<extends<<"Client[property]"<<endl;
-
+    indent(f_service_) << "Thrift.inherits(" <<
+        js_namespace(tservice->get_program()) <<
+        service_name_ << "Client, " <<
+        tservice->get_extends()->get_name() << "Client)" << endl;
+  } else {
+      //init prototype
+      indent(f_service_) <<  js_namespace(tservice->get_program())<<service_name_ << "Client.prototype = {}"<<endl;
   }
 
-  //init prototype
-  f_service_ <<  js_namespace(tservice->get_program())<<service_name_ << "Client.prototype = {}"<<endl;
-
-
   // Generate client method implementations
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::const_iterator f_iter;
@@ -1231,7 +1259,7 @@ void t_js_generator::generate_deserialize_struct(ofstream &out,
                                                    t_struct* tstruct,
                                                    string prefix) {
     out <<
-        indent() << prefix << " = new " <<  js_type_namespace(tstruct->get_program())<<tstruct->get_name() << "()" << endl <<
+        indent() << prefix << " = new " <<  js_type_namespace(tstruct)<<tstruct->get_name() << "()" << endl <<
         indent() << prefix << ".read(input)" << endl;
 
 }
@@ -1478,7 +1506,7 @@ void t_js_generator::generate_serialize_container(ofstream &out,
         "output.writeMapBegin(" <<
         type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
         type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
-        prefix << ".length)" << endl;
+        "Thrift.objectLength(" << prefix << "))" << endl;
   } else if (ttype->is_set()) {
     indent(out) <<
       "output.writeSetBegin(" <<
@@ -1625,7 +1653,7 @@ string t_js_generator::declare_field(t_field* tfield, bool init, bool obj) {
       result += " = null";
     } else if (type->is_struct() || type->is_xception()) {
       if (obj) {
-          result += " = new " +js_type_namespace(type->get_program()) + type->get_name() + "()";
+          result += " = new " +js_type_namespace(type) + type->get_name() + "()";
       } else {
         result += " = null";
       }
index b7ad5f2..e259f5a 100644 (file)
@@ -24,9 +24,12 @@ namespace Thrift.Transport
        public class TFramedTransport : TTransport
        {
                protected TTransport transport = null;
-               protected MemoryStream writeBuffer = new MemoryStream(1024);
+               protected MemoryStream writeBuffer;
                protected MemoryStream readBuffer = null;
 
+               private const int header_size = 4;
+               private static byte[] header_dummy = new byte[header_size]; // used as header placeholder while initilizing new write buffer
+
                public class Factory : TTransportFactory
                {
                        public override TTransport GetTransport(TTransport trans)
@@ -35,7 +38,12 @@ namespace Thrift.Transport
                        }
                }
 
-               public TFramedTransport(TTransport transport)
+               public TFramedTransport()
+               {
+                       InitWriteBuffer();
+               }
+
+               public TFramedTransport(TTransport transport) : this()
                {
                        this.transport = transport;
                }
@@ -77,8 +85,8 @@ namespace Thrift.Transport
 
                private void ReadFrame()
                {
-                       byte[] i32rd = new byte[4];
-                       transport.ReadAll(i32rd, 0, 4);
+                       byte[] i32rd = new byte[header_size];
+                       transport.ReadAll(i32rd, 0, header_size);
                        int size =
                                ((i32rd[0] & 0xff) << 24) |
                                ((i32rd[1] & 0xff) << 16) |
@@ -99,16 +107,31 @@ namespace Thrift.Transport
                {
                        byte[] buf = writeBuffer.GetBuffer();
                        int len = (int)writeBuffer.Length;
-                       writeBuffer = new MemoryStream(writeBuffer.Capacity);
-
-                       byte[] i32out = new byte[4];
-                       i32out[0] = (byte)(0xff & (len >> 24));
-                       i32out[1] = (byte)(0xff & (len >> 16));
-                       i32out[2] = (byte)(0xff & (len >> 8));
-                       i32out[3] = (byte)(0xff & (len));
-                       transport.Write(i32out, 0, 4);
+                       int data_len = len - header_size;
+                       if ( data_len < 0 )
+                               throw new System.InvalidOperationException (); // logic error actually
+
+                       InitWriteBuffer();
+
+                       // Inject message header into the reserved buffer space
+                       buf[0] = (byte)(0xff & (data_len >> 24));
+                       buf[1] = (byte)(0xff & (data_len >> 16));
+                       buf[2] = (byte)(0xff & (data_len >> 8));
+                       buf[3] = (byte)(0xff & (data_len));
+
+                       // Send the entire message at once
                        transport.Write(buf, 0, len);
+
                        transport.Flush();
                }
+
+               private void InitWriteBuffer ()
+               {
+                       // Create new buffer instance
+                       writeBuffer = new MemoryStream(1024);
+
+                       // Reserve space for message header to be put right before sending it out
+                       writeBuffer.Write ( header_dummy, 0, header_size );
+               }
        }
 }
index b28c312..98f7194 100644 (file)
@@ -183,7 +183,6 @@ public class TAsyncClientManager {
 
   /** Comparator used in TreeSet */
   private static class TAsyncMethodCallTimeoutComparator implements Comparator<TAsyncMethodCall> {
-    @Override
     public int compare(TAsyncMethodCall left, TAsyncMethodCall right) {
       if (left.getTimeoutTimestamp() == right.getTimeoutTimestamp()) {
         return (int)(left.getSequenceId() - right.getSequenceId());
index 9b92658..c06e27a 100644 (file)
@@ -713,5 +713,20 @@ Thrift.Protocol.prototype = {
    
 }
 
+Thrift.objectLength = function(obj) {
+  var length = 0;
+  for (k in obj) {
+    if (obj.hasOwnProperty(k)) {
+      length++;
+    }
+  }
+  return length;
+}
 
-
+Thirft.inherits = function(constructor, superConstructor) {
+  // Prototypal Inheritance
+  // http://javascript.crockford.com/prototypal.html
+  function F() {}
+  F.prototype = superConstructor.prototype;
+  constructor.prototype = new F();
+}
index 73f772b..53ca106 100644 (file)
@@ -85,7 +85,7 @@ TApplicationException.prototype.read = function(input) {
           case 1:
               if( ret.ftype == Type.STRING ){
                   ret = input.readString()
-                  this.message = ret.value
+                  this.message = ret
               } else {
                   ret = input.skip(ret.ftype)
               }
@@ -94,7 +94,7 @@ TApplicationException.prototype.read = function(input) {
           case 2:
               if( ret.ftype == Type.I32 ){
                   ret = input.readI32()
-                  this.type = ret.value
+                  this.type = ret
               } else {
                   ret   = input.skip(ret.ftype)
               }
@@ -128,3 +128,11 @@ TApplicationException.prototype.write = function(output){
   output.writeFieldStop()
   output.writeStructEnd()
 }
+
+exports.objectLength = function(obj) {
+  return Object.keys(obj).length;
+}
+
+exports.inherits = function(constructor, superConstructor) {
+  sys.inherits(constructor, superConstructor);
+}
index 1d7c75e..60fc995 100644 (file)
@@ -39,7 +39,7 @@ namespace Test
                                int port = 9090;
                                string url = null;
                                int numThreads = 1;
-                               bool buffered = false;
+                               bool buffered = false, framed = false;
 
                                try
                                {
@@ -67,6 +67,11 @@ namespace Test
                                                        buffered = true;
                                                        Console.WriteLine("Using buffered sockets");
                                                }
+                                               else if (args[i] == "-f" || args[i] == "-framed")
+                                               {
+                                                       framed = true;
+                                                       Console.WriteLine("Using framed transport");
+                                               }
                                                else if (args[i] == "-t")
                                                {
                                                        numThreads = Convert.ToInt32(args[++i]);
@@ -89,16 +94,13 @@ namespace Test
                                        threads[test] = t;
                                        if (url == null)
                                        {
-                                               TSocket socket = new TSocket(host, port);
+                                               TTransport trans = new TSocket(host, port);
                                                if (buffered)
-                                               {
-                                                       TBufferedTransport buffer = new TBufferedTransport(socket);
-                                                       t.Start(buffer);
-                                               }
-                                               else
-                                               {
-                                                       t.Start(socket);
-                                               }
+                                                       trans = new TBufferedTransport(trans as TStreamTransport);
+                                               if (framed)
+                                                       trans = new TFramedTransport(trans);
+                                                       
+                                               t.Start(trans);
                                        }
                                        else
                                        {
@@ -428,6 +430,12 @@ namespace Test
 
                        Console.WriteLine("Test Oneway(1)");
                        client.testOneway(1);
+
+                       Console.Write("Test Calltime()");
+                       var startt = DateTime.UtcNow;
+                       for ( int k=0; k<1000; ++k )
+                               client.testVoid();
+                       Console.WriteLine(" = " + (DateTime.UtcNow - startt).TotalSeconds.ToString() + " ms a testVoid() call" );
                }
        }
 }
index e370640..894ec9c 100644 (file)
@@ -301,7 +301,7 @@ namespace Test
                {
                        try
                        {
-                               bool useBufferedSockets = false;
+                               bool useBufferedSockets = false, useFramed = false;
                                int port = 9090;
                                if (args.Length > 0)
                                {
@@ -309,7 +309,23 @@ namespace Test
 
                                        if (args.Length > 1)
                                        {
-                                               bool.TryParse(args[1], out useBufferedSockets);
+                                               if ( args[1] == "raw" )
+                                               {
+                                                       // as default
+                                               }
+                                               else if ( args[1] == "buffered" )
+                                               {
+                                                       useBufferedSockets = true;
+                                               }
+                                               else if ( args[1] == "framed" )
+                                               {
+                                                       useFramed = true;
+                                               }
+                                               else
+                                               {
+                                                       // Fall back to the older boolean syntax
+                                                       bool.TryParse(args[1], out useBufferedSockets);
+                                               }
                                        }
                                }
 
@@ -320,10 +336,12 @@ namespace Test
                                // Transport
                                TServerSocket tServerSocket = new TServerSocket(port, 0, useBufferedSockets);
 
-                               TServer serverEngine;
-
                                // Simple Server
-                               serverEngine = new TSimpleServer(testProcessor, tServerSocket);
+                               TServer serverEngine;
+                               if ( useFramed )
+                                       serverEngine = new TSimpleServer(testProcessor, tServerSocket, new TFramedTransport.Factory());
+                               else
+                                       serverEngine = new TSimpleServer(testProcessor, tServerSocket);
 
                                // ThreadPool Server
                                // serverEngine = new TThreadPoolServer(testProcessor, tServerSocket);
@@ -334,7 +352,10 @@ namespace Test
                                testHandler.server = serverEngine;
 
                                // Run it
-                               Console.WriteLine("Starting the server on port " + port + (useBufferedSockets ? " with buffered socket" : "") + "...");
+                               Console.WriteLine("Starting the server on port " + port + 
+                                       (useBufferedSockets ? " with buffered socket" : "") + 
+                                       (useFramed ? " with framed transport" : "") + 
+                                       "...");
                                serverEngine.Serve();
 
                        }