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 0609ca2..1f92670 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,7 @@
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-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 4aa6811..a654fc9 100644
--- a/compiler/cpp/src/generate/t_js_generator.cc
+++ b/compiler/cpp/src/generate/t_js_generator.cc
@@ -157,6 +157,7 @@
*/
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 @@
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) {
@@ -287,6 +292,26 @@
}
/**
+ * 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.
*/
void t_js_generator::close_generator() {
@@ -311,7 +336,7 @@
* @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 @@
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 @@
} 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 @@
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 @@
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 @@
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 @@
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 @@
"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 @@
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 b7ad5f2..e259f5a 100644
--- a/lib/csharp/src/Transport/TFramedTransport.cs
+++ b/lib/csharp/src/Transport/TFramedTransport.cs
@@ -24,9 +24,12 @@
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 @@
}
}
- public TFramedTransport(TTransport transport)
+ public TFramedTransport()
+ {
+ InitWriteBuffer();
+ }
+
+ public TFramedTransport(TTransport transport) : this()
{
this.transport = transport;
}
@@ -77,8 +85,8 @@
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 @@
{
byte[] buf = writeBuffer.GetBuffer();
int len = (int)writeBuffer.Length;
- writeBuffer = new MemoryStream(writeBuffer.Capacity);
+ int data_len = len - header_size;
+ if ( data_len < 0 )
+ throw new System.InvalidOperationException (); // logic error actually
- 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);
+ 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 b28c312..98f7194 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 @@
/** 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());
diff --git a/lib/js/thrift.js b/lib/js/thrift.js
index 9b92658..c06e27a 100644
--- a/lib/js/thrift.js
+++ b/lib/js/thrift.js
@@ -713,5 +713,20 @@
}
+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 73f772b..53ca106 100644
--- a/lib/nodejs/lib/thrift/thrift.js
+++ b/lib/nodejs/lib/thrift/thrift.js
@@ -85,7 +85,7 @@
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 @@
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 @@
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 1d7c75e..60fc995 100644
--- a/test/csharp/ThriftTest/TestClient.cs
+++ b/test/csharp/ThriftTest/TestClient.cs
@@ -39,7 +39,7 @@
int port = 9090;
string url = null;
int numThreads = 1;
- bool buffered = false;
+ bool buffered = false, framed = false;
try
{
@@ -67,6 +67,11 @@
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 @@
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 @@
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 e370640..894ec9c 100644
--- a/test/csharp/ThriftTest/TestServer.cs
+++ b/test/csharp/ThriftTest/TestServer.cs
@@ -301,7 +301,7 @@
{
try
{
- bool useBufferedSockets = false;
+ bool useBufferedSockets = false, useFramed = false;
int port = 9090;
if (args.Length > 0)
{
@@ -309,7 +309,23 @@
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 @@
// 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 @@
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();
}