From: T Jake Luciani Date: Mon, 31 Jan 2011 01:57:14 +0000 (+0000) Subject: merge changes for 0.6 rc2 X-Git-Tag: 0.6.0~1 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=68634a0bac61d41b8ce057d0c9086aea82f4d853;p=common%2Fthrift.git merge changes for 0.6 rc2 git-svn-id: https://svn.apache.org/repos/asf/thrift/branches/0.6.x@1065464 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0609ca22..1f92670d 100644 --- 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) diff --git a/compiler/cpp/src/generate/t_js_generator.cc b/compiler/cpp/src/generate/t_js_generator.cc index 4aa68116..a654fc98 100644 --- a/compiler/cpp/src/generate/t_js_generator.cc +++ b/compiler/cpp/src/generate/t_js_generator.cc @@ -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& 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())<get_name()<<" = { "<get_name()<<" = { "< constants = tenum->get_constants(); vector::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& fields = ((t_struct*)type)->get_members(); vector::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)"<get_program())<get_name()<<"[property] = Thrift.TException[property]"<get_program())<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())<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 "<get_program()) << service_name_<<"Client[property] = "<get_program()) << + service_name_ << "Client, " << + tservice->get_extends()->get_name() << "Client)" << endl; + } else { + //init prototype + indent(f_service_) << js_namespace(tservice->get_program())<get_program())< functions = tservice->get_functions(); vector::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())<get_name() << "()" << endl << + indent() << prefix << " = new " << js_type_namespace(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"; } diff --git a/lib/csharp/src/Transport/TFramedTransport.cs b/lib/csharp/src/Transport/TFramedTransport.cs index b7ad5f24..e259f5a5 100644 --- a/lib/csharp/src/Transport/TFramedTransport.cs +++ b/lib/csharp/src/Transport/TFramedTransport.cs @@ -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 ); + } } } diff --git a/lib/java/src/org/apache/thrift/async/TAsyncClientManager.java b/lib/java/src/org/apache/thrift/async/TAsyncClientManager.java index b28c3125..98f71947 100644 --- a/lib/java/src/org/apache/thrift/async/TAsyncClientManager.java +++ b/lib/java/src/org/apache/thrift/async/TAsyncClientManager.java @@ -183,7 +183,6 @@ public class TAsyncClientManager { /** Comparator used in TreeSet */ private static class TAsyncMethodCallTimeoutComparator implements Comparator { - @Override public int compare(TAsyncMethodCall left, TAsyncMethodCall right) { if (left.getTimeoutTimestamp() == right.getTimeoutTimestamp()) { return (int)(left.getSequenceId() - right.getSequenceId()); diff --git a/lib/js/thrift.js b/lib/js/thrift.js index 9b92658d..c06e27a0 100644 --- a/lib/js/thrift.js +++ b/lib/js/thrift.js @@ -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(); +} diff --git a/lib/nodejs/lib/thrift/thrift.js b/lib/nodejs/lib/thrift/thrift.js index 73f772b2..53ca1066 100644 --- a/lib/nodejs/lib/thrift/thrift.js +++ b/lib/nodejs/lib/thrift/thrift.js @@ -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); +} diff --git a/test/csharp/ThriftTest/TestClient.cs b/test/csharp/ThriftTest/TestClient.cs index 1d7c75ea..60fc995e 100644 --- a/test/csharp/ThriftTest/TestClient.cs +++ b/test/csharp/ThriftTest/TestClient.cs @@ -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" ); } } } diff --git a/test/csharp/ThriftTest/TestServer.cs b/test/csharp/ThriftTest/TestServer.cs index e3706404..894ec9c2 100644 --- a/test/csharp/ThriftTest/TestServer.cs +++ b/test/csharp/ThriftTest/TestServer.cs @@ -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(); }