From b82445fe8110440c3270951292819ce49731c17f Mon Sep 17 00:00:00 2001 From: Konrad Grochowski Date: Sun, 14 Sep 2014 13:09:48 +0200 Subject: [PATCH 1/4] THRIFT-2704 - compiler: T_ONEWAY type used for oneway methods instead of T_CALL --- compiler/cpp/src/generate/t_cpp_generator.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc index f019ba86a4b..ce298ad7469 100755 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -2756,7 +2756,9 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style) indent() << "int32_t cseqid = 0;" << endl << indent() << _this << "oprot_->writeMessageBegin(\"" << (*f_iter)->get_name() << - "\", ::apache::thrift::protocol::T_CALL, cseqid);" << endl << + "\", ::apache::thrift::protocol::" << + ((*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL") << + ", cseqid);" << endl << endl << indent() << argsname << " args;" << endl; From 22207dea6764b79f2a27cc6de4a3036b598c24f0 Mon Sep 17 00:00:00 2001 From: Konrad Grochowski Date: Tue, 16 Sep 2014 12:23:19 +0200 Subject: [PATCH 2/4] Compact protocol - fixed decoding message type T_ONEWAY message type was cut out due to wrong mask on decode --- lib/cpp/src/thrift/protocol/TCompactProtocol.h | 1 + lib/cpp/src/thrift/protocol/TCompactProtocol.tcc | 2 +- lib/csharp/src/Protocol/TCompactProtocol.cs | 3 ++- lib/d/src/thrift/protocol/compact.d | 3 ++- lib/go/thrift/compact_protocol.go | 3 ++- lib/hs/src/Thrift/Protocol/Compact.hs | 3 ++- .../src/org/apache/thrift/protocol/TCompactProtocol.java | 3 ++- lib/nodejs/lib/thrift/protocol.js | 9 ++++++++- lib/php/lib/Thrift/Protocol/TCompactProtocol.php | 4 ++-- lib/py/src/protocol/TCompactProtocol.py | 3 ++- lib/rb/ext/compact_protocol.c | 4 +++- lib/rb/lib/thrift/protocol/compact_protocol.rb | 3 ++- 12 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.h b/lib/cpp/src/thrift/protocol/TCompactProtocol.h index d6da745704a..ce60b4523de 100644 --- a/lib/cpp/src/thrift/protocol/TCompactProtocol.h +++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.h @@ -39,6 +39,7 @@ class TCompactProtocolT static const int8_t VERSION_N = 1; static const int8_t VERSION_MASK = 0x1f; // 0001 1111 static const int8_t TYPE_MASK = (int8_t)0xE0u; // 1110 0000 + static const int8_t TYPE_BITS = 0x07; // 0000 0111 static const int32_t TYPE_SHIFT_AMOUNT = 5; Transport_* trans_; diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc index a0955fc8deb..85dde6c88f1 100644 --- a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc +++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc @@ -433,7 +433,7 @@ uint32_t TCompactProtocolT::readMessageBegin( throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version"); } - messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03); + messageType = (TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); rsize += readVarint32(seqid); rsize += readString(name); diff --git a/lib/csharp/src/Protocol/TCompactProtocol.cs b/lib/csharp/src/Protocol/TCompactProtocol.cs index 2c94c0c546c..c992e9b7d85 100644 --- a/lib/csharp/src/Protocol/TCompactProtocol.cs +++ b/lib/csharp/src/Protocol/TCompactProtocol.cs @@ -41,6 +41,7 @@ public class TCompactProtocol : TProtocol private const byte VERSION = 1; private const byte VERSION_MASK = 0x1f; // 0001 1111 private const byte TYPE_MASK = 0xE0; // 1110 0000 + private const byte TYPE_BITS = 0x07; // 0000 0111 private const int TYPE_SHIFT_AMOUNT = 5; /** @@ -490,7 +491,7 @@ public override TMessage ReadMessageBegin() { throw new TProtocolException("Expected version " + VERSION + " but got " + version); } - byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03); + byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); int seqid = (int)ReadVarint32(); String messageName = ReadString(); return new TMessage(messageName, (TMessageType)type, seqid); diff --git a/lib/d/src/thrift/protocol/compact.d b/lib/d/src/thrift/protocol/compact.d index e970fd1b7b1..e03b67d4f4f 100644 --- a/lib/d/src/thrift/protocol/compact.d +++ b/lib/d/src/thrift/protocol/compact.d @@ -259,7 +259,7 @@ final class TCompactProtocol(Transport = TTransport) if ( TProtocolException.Type.BAD_VERSION); } - msg.type = cast(TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03); + msg.type = cast(TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); msg.seqid = readVarint32(); msg.name = readString(); @@ -589,6 +589,7 @@ private: enum VERSION_N = 1; enum VERSION_MASK = 0b0001_1111; enum TYPE_MASK = 0b1110_0000; + enum TYPE_BITS = 0b0000_0111; enum TYPE_SHIFT_AMOUNT = 5; // Probably need to implement a better stack at some point. diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go index c275cf43825..0857a7a425f 100644 --- a/lib/go/thrift/compact_protocol.go +++ b/lib/go/thrift/compact_protocol.go @@ -31,6 +31,7 @@ const ( COMPACT_VERSION = 1 COMPACT_VERSION_MASK = 0x1f COMPACT_TYPE_MASK = 0x0E0 + COMPACT_TYPE_BITS = 0x07 COMPACT_TYPE_SHIFT_AMOUNT = 5 ) @@ -335,7 +336,7 @@ func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, } versionAndType, err := p.ReadByte() version := versionAndType & COMPACT_VERSION_MASK - typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & 0x03) + typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS) if err != nil { return } diff --git a/lib/hs/src/Thrift/Protocol/Compact.hs b/lib/hs/src/Thrift/Protocol/Compact.hs index c3bd22d9af5..a329f4ec2b5 100644 --- a/lib/hs/src/Thrift/Protocol/Compact.hs +++ b/lib/hs/src/Thrift/Protocol/Compact.hs @@ -60,6 +60,7 @@ protocolID = 0x82 -- 1000 0010 version = 0x01 versionMask = 0x1f -- 0001 1111 typeMask = 0xe0 -- 1110 0000 +typeBits = 0x07 -- 0000 0111 typeShiftAmount :: Int typeShiftAmount = 5 @@ -81,7 +82,7 @@ instance Protocol CompactProtocol where w <- fromIntegral <$> P.anyWord8 let ver = w .&. versionMask when (ver /= version) $ error "Bad Protocol version" - let typ = (w `shiftR` typeShiftAmount) .&. 0x03 + let typ = (w `shiftR` typeShiftAmount) .&. typeBits seqId <- parseVarint zigZagToI32 TString name <- parseCompactValue T_STRING return (decodeUtf8 name, toEnum $ fromIntegral $ typ, seqId) diff --git a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java index 0a653a1b2ba..5973fcd3e44 100644 --- a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java +++ b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java @@ -89,6 +89,7 @@ public TProtocol getProtocol(TTransport trans) { private static final byte VERSION = 1; private static final byte VERSION_MASK = 0x1f; // 0001 1111 private static final byte TYPE_MASK = (byte)0xE0; // 1110 0000 + private static final byte TYPE_BITS = 0x07; // 0000 0111 private static final int TYPE_SHIFT_AMOUNT = 5; /** @@ -506,7 +507,7 @@ public TMessage readMessageBegin() throws TException { if (version != VERSION) { throw new TProtocolException("Expected version " + VERSION + " but got " + version); } - byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03); + byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); int seqid = readVarint32(); String messageName = readString(); return new TMessage(messageName, type, seqid); diff --git a/lib/nodejs/lib/thrift/protocol.js b/lib/nodejs/lib/thrift/protocol.js index 9bfe2682529..6c4d9e611e3 100644 --- a/lib/nodejs/lib/thrift/protocol.js +++ b/lib/nodejs/lib/thrift/protocol.js @@ -424,6 +424,13 @@ TCompactProtocol.VERSION_MASK = 0x1f; //0001 1111 */ TCompactProtocol.TYPE_MASK = -32; //1110 0000 +/** + * Compact Protocol message type bits for ensuring message type bit size. + * @readonly + * @const {number} TYPE_BITS + */ +TCompactProtocol.TYPE_BITS = 7; //0000 0111 + /** * Compact Protocol message type shift amount for combining protocol version and message type in one byte. * @readonly @@ -837,7 +844,7 @@ TCompactProtocol.prototype.readMessageBegin = function() { if (version != TCompactProtocol.VERSION_N) { throw new TProtocolException(BAD_VERSION, "Bad protocol version " + version); } - var type = ((versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & 0x03); + var type = ((versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & TCompactProtocol.TYPE_BITS); //Read SeqId var seqid = this.readVarint32(); diff --git a/lib/php/lib/Thrift/Protocol/TCompactProtocol.php b/lib/php/lib/Thrift/Protocol/TCompactProtocol.php index 880da25a0ea..337511ef57a 100644 --- a/lib/php/lib/Thrift/Protocol/TCompactProtocol.php +++ b/lib/php/lib/Thrift/Protocol/TCompactProtocol.php @@ -61,6 +61,7 @@ class TCompactProtocol extends TProtocol { const VERSION = 1; const PROTOCOL_ID = 0x82; const TYPE_MASK = 0xe0; + const TYPE_BITS = 0x07; const TYPE_SHIFT_AMOUNT = 5; protected static $ctypes = array( @@ -381,8 +382,7 @@ public function readMessageBegin(&$name, &$type, &$seqid) { } $verType = 0; $result += $this->readUByte($verType); - $type = ($verType & TCompactProtocol::TYPE_MASK) >> - TCompactProtocol::TYPE_SHIFT_AMOUNT; + $type = ($verType >> TCompactProtocol::TYPE_SHIFT_AMOUNT) & TCompactProtocol::TYPE_BITS; $version = $verType & TCompactProtocol::VERSION_MASK; if ($version != TCompactProtocol::VERSION) { throw new TProtocolException('Bad version in TCompact message'); diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py index c34edb80baf..79deda8fd73 100644 --- a/lib/py/src/protocol/TCompactProtocol.py +++ b/lib/py/src/protocol/TCompactProtocol.py @@ -120,6 +120,7 @@ class TCompactProtocol(TProtocolBase): VERSION = 1 VERSION_MASK = 0x1f TYPE_MASK = 0xe0 + TYPE_BITS = 0x07 TYPE_SHIFT_AMOUNT = 5 def __init__(self, trans): @@ -310,7 +311,7 @@ def readMessageBegin(self): raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad protocol id in the message: %d' % proto_id) ver_type = self.__readUByte() - type = (ver_type & self.TYPE_MASK) >> self.TYPE_SHIFT_AMOUNT + type = (ver_type >> self.TYPE_SHIFT_AMOUNT) & self.TYPE_BITS version = ver_type & self.VERSION_MASK if version != self.VERSION: raise TProtocolException(TProtocolException.BAD_VERSION, diff --git a/lib/rb/ext/compact_protocol.c b/lib/rb/ext/compact_protocol.c index 725d3381a33..c0f46b95848 100644 --- a/lib/rb/ext/compact_protocol.c +++ b/lib/rb/ext/compact_protocol.c @@ -40,6 +40,7 @@ static ID rbuf_ivar_id; static int VERSION; static int VERSION_MASK; static int TYPE_MASK; +static int TYPE_BITS; static int TYPE_SHIFT_AMOUNT; static int PROTOCOL_ID; @@ -450,7 +451,7 @@ VALUE rb_thrift_compact_proto_read_message_begin(VALUE self) { rb_exc_raise(get_protocol_exception(INT2FIX(-1), rb_str_new2(buf))); } - int8_t type = (version_and_type >> TYPE_SHIFT_AMOUNT) & 0x03; + int8_t type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS; int32_t seqid = read_varint64(self); VALUE messageName = rb_thrift_compact_proto_read_string(self); return rb_ary_new3(3, messageName, INT2FIX(type), INT2NUM(seqid)); @@ -570,6 +571,7 @@ static void Init_constants() { VERSION = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION"))); VERSION_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION_MASK"))); TYPE_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_MASK"))); + TYPE_BITS = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_BITS"))); TYPE_SHIFT_AMOUNT = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("TYPE_SHIFT_AMOUNT"))); PROTOCOL_ID = FIX2INT(rb_const_get(thrift_compact_protocol_class, rb_intern("PROTOCOL_ID"))); diff --git a/lib/rb/lib/thrift/protocol/compact_protocol.rb b/lib/rb/lib/thrift/protocol/compact_protocol.rb index 07a67920745..605eea67f00 100644 --- a/lib/rb/lib/thrift/protocol/compact_protocol.rb +++ b/lib/rb/lib/thrift/protocol/compact_protocol.rb @@ -24,6 +24,7 @@ class CompactProtocol < BaseProtocol VERSION = 1 VERSION_MASK = 0x1f TYPE_MASK = 0xE0 + TYPE_BITS = 0x07 TYPE_SHIFT_AMOUNT = 5 TSTOP = ["", Types::STOP, 0] @@ -231,7 +232,7 @@ def read_message_begin raise ProtocolException.new("Expected version #{VERSION} but got #{version}"); end - type = (version_and_type >> TYPE_SHIFT_AMOUNT) & 0x03 + type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS seqid = read_varint32() messageName = read_string() [messageName, type, seqid] From 6aca3ff971e58af0d3f1a9fb0e310b242b47ce88 Mon Sep 17 00:00:00 2001 From: Konrad Grochowski Date: Tue, 16 Sep 2014 13:29:00 +0200 Subject: [PATCH 3/4] THRIFT-2704 - compiler: ONEWAY message type used in generated code more languages support added support for ONEWAY message type to Haskell library --- compiler/cpp/src/generate/t_as3_generator.cc | 4 +++- compiler/cpp/src/generate/t_c_glib_generator.cc | 6 ++++-- compiler/cpp/src/generate/t_cocoa_generator.cc | 2 +- compiler/cpp/src/generate/t_csharp_generator.cc | 4 +++- compiler/cpp/src/generate/t_delphi_generator.cc | 4 +++- compiler/cpp/src/generate/t_go_generator.cc | 5 ++++- compiler/cpp/src/generate/t_hs_generator.cc | 3 ++- compiler/cpp/src/generate/t_java_generator.cc | 5 ++++- compiler/cpp/src/generate/t_javame_generator.cc | 4 +++- compiler/cpp/src/generate/t_js_generator.cc | 12 ++++++++++-- compiler/cpp/src/generate/t_lua_generator.cc | 5 +++-- compiler/cpp/src/generate/t_ocaml_generator.cc | 4 +++- compiler/cpp/src/generate/t_perl_generator.cc | 4 +++- compiler/cpp/src/generate/t_php_generator.cc | 12 +++++++++--- compiler/cpp/src/generate/t_py_generator.cc | 9 +++++---- lib/hs/src/Thrift/Types.hs | 5 ++++- 16 files changed, 64 insertions(+), 24 deletions(-) diff --git a/compiler/cpp/src/generate/t_as3_generator.cc b/compiler/cpp/src/generate/t_as3_generator.cc index a965aabf601..42486d67fab 100644 --- a/compiler/cpp/src/generate/t_as3_generator.cc +++ b/compiler/cpp/src/generate/t_as3_generator.cc @@ -1677,7 +1677,9 @@ void t_as3_generator::generate_service_client(t_service* tservice) { // Serialize the request f_service_ << - indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", TMessageType.CALL, seqid_));" << endl << + indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", " << + ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") << + ", seqid_));" << endl << indent() << "var args:" << argsname << " = new " << argsname << "();" << endl; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { diff --git a/compiler/cpp/src/generate/t_c_glib_generator.cc b/compiler/cpp/src/generate/t_c_glib_generator.cc index c726b0c5aa7..dbb8a2a47e2 100644 --- a/compiler/cpp/src/generate/t_c_glib_generator.cc +++ b/compiler/cpp/src/generate/t_c_glib_generator.cc @@ -1517,6 +1517,8 @@ void t_c_glib_generator::generate_service_client(t_service *tservice) { function_signature (&send_function) << endl; scope_up(f_service_); + string reqType = (*f_iter)->is_oneway() ? "T_ONEWAY" : "T_CALL"; + // Serialize the request f_service_ << indent() << "gint32 cseqid = 0;" << endl << @@ -1524,8 +1526,8 @@ void t_c_glib_generator::generate_service_client(t_service *tservice) { this->nspace_uc << base_service_name_uc << "_CLIENT (iface)->output_protocol;" << endl << endl << - indent() << "if (thrift_protocol_write_message_begin (protocol, \"" << - name << "\", T_CALL, cseqid, error) < 0)" << endl << + indent() << "if (thrift_protocol_write_message_begin (protocol, \"" + << name << "\", " << reqType << ", cseqid, error) < 0)" << endl << indent() << " return FALSE;" << endl << endl; diff --git a/compiler/cpp/src/generate/t_cocoa_generator.cc b/compiler/cpp/src/generate/t_cocoa_generator.cc index 20973a3c0ee..f765f7d26cd 100644 --- a/compiler/cpp/src/generate/t_cocoa_generator.cc +++ b/compiler/cpp/src/generate/t_cocoa_generator.cc @@ -1401,7 +1401,7 @@ void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& o // Serialize the request out << indent() << "[outProtocol writeMessageBeginWithName: @\"" << funname << "\"" << - " type: TMessageType_CALL" << + ((*f_iter)->is_oneway() ? " type: TMessageType_ONEWAY" : " type: TMessageType_CALL") << " sequenceID: 0];" << endl; out << diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc index 7944df0ef36..1d66cefed9b 100644 --- a/compiler/cpp/src/generate/t_csharp_generator.cc +++ b/compiler/cpp/src/generate/t_csharp_generator.cc @@ -1718,7 +1718,9 @@ void t_csharp_generator::generate_service_client(t_service* tservice) { scope_up(f_service_); f_service_ << - indent() << "oprot_.WriteMessageBegin(new TMessage(\"" << funname << "\", TMessageType.Call, seqid_));" << endl << + indent() << "oprot_.WriteMessageBegin(new TMessage(\"" << funname << "\", " << + ((*f_iter)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") << + ", seqid_));" << endl << indent() << argsname << " args = new " << argsname << "();" << endl; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc index 5f378f00193..19b82724369 100644 --- a/compiler/cpp/src/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/generate/t_delphi_generator.cc @@ -1777,7 +1777,9 @@ void t_delphi_generator::generate_service_client(t_service* tservice) { indent_impl(s_service_impl) << "seqid_ := seqid_ + 1;" << endl; indent_impl(s_service_impl) << - msgvar << " := Thrift.Protocol.TMessageImpl.Create('" << funname << "', TMessageType.Call, seqid_);" << endl; + msgvar << " := Thrift.Protocol.TMessageImpl.Create('" << funname << "', " << + ((*f_iter)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") << + ", seqid_);" << endl; indent_impl(s_service_impl) << "oprot_.WriteMessageBegin( " << msgvar << " );" << endl; diff --git a/compiler/cpp/src/generate/t_go_generator.cc b/compiler/cpp/src/generate/t_go_generator.cc index 9a3e9099e63..54ad887334e 100644 --- a/compiler/cpp/src/generate/t_go_generator.cc +++ b/compiler/cpp/src/generate/t_go_generator.cc @@ -1803,7 +1803,10 @@ void t_go_generator::generate_service_client(t_service* tservice) indent() << " p.OutputProtocol = oprot" << endl << indent() << "}" << endl << indent() << "p.SeqId++" << endl << - indent() << "if err = oprot.WriteMessageBegin(\"" << (*f_iter)->get_name() << "\", thrift.CALL, p.SeqId); err != nil {" << endl; + indent() << "if err = oprot.WriteMessageBegin(\"" + << (*f_iter)->get_name() << "\", " + << ((*f_iter)->is_oneway() ? "thrift.ONEWAY" : "thrift.CALL") + << ", p.SeqId); err != nil {" << endl; indent_up(); f_service_ << indent() << "return" << endl; diff --git a/compiler/cpp/src/generate/t_hs_generator.cc b/compiler/cpp/src/generate/t_hs_generator.cc index fff7e5357e8..2f75dafa0ad 100644 --- a/compiler/cpp/src/generate/t_hs_generator.cc +++ b/compiler/cpp/src/generate/t_hs_generator.cc @@ -1113,7 +1113,8 @@ void t_hs_generator::generate_service_client(t_service* tservice) { // Serialize the request header string fname = (*f_iter)->get_name(); - indent(f_client_) << "T.writeMessageBegin op (\"" << fname << "\", T.M_CALL, seqn)" << endl; + string msgType = (*f_iter)->is_oneway() ? "T.M_ONEWAY" : "T.M_CALL"; + indent(f_client_) << "T.writeMessageBegin op (\"" << fname << "\", " << msgType << ", seqn)" << endl; indent(f_client_) << "write_" << argsname << " op (" << argsname << "{"; bool first = true; diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index 3a556a5a7de..ddf4c91c296 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -2814,7 +2814,10 @@ void t_java_generator::generate_service_async_client(t_service* tservice) { // Serialize request // NOTE we are leaving seqid as 0, for now (see above) f_service_ << - indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\"" << funname << "\", org.apache.thrift.protocol.TMessageType.CALL, 0));" << endl << + indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\"" << + funname << "\", org.apache.thrift.protocol." << + ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") << + ", 0));" << endl << indent() << args_name << " args = new " << args_name << "();" << endl; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { diff --git a/compiler/cpp/src/generate/t_javame_generator.cc b/compiler/cpp/src/generate/t_javame_generator.cc index 6d029792ce4..c28571e9b8d 100644 --- a/compiler/cpp/src/generate/t_javame_generator.cc +++ b/compiler/cpp/src/generate/t_javame_generator.cc @@ -2109,7 +2109,9 @@ void t_javame_generator::generate_service_client(t_service* tservice) { // Serialize the request f_service_ << - indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", TMessageType.CALL, ++seqid_));" << endl << + indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", " << + ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") << + ", ++seqid_));" << endl << indent() << argsname << " args = new " << argsname << "();" << endl; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { diff --git a/compiler/cpp/src/generate/t_js_generator.cc b/compiler/cpp/src/generate/t_js_generator.cc index 32cb1629764..7711aa5c5b1 100644 --- a/compiler/cpp/src/generate/t_js_generator.cc +++ b/compiler/cpp/src/generate/t_js_generator.cc @@ -1350,12 +1350,20 @@ void t_js_generator::generate_service_client(t_service* tservice) { std::string argsname = js_namespace(program_)+ service_name_ + "_" + (*f_iter)->get_name() + "_args"; + std::string messageType + = (*f_iter)->is_oneway() ? "Thrift.MessageType.ONEWAY" : "Thrift.MessageType.CALL"; + // Serialize the request header if (gen_node_) { - f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() << "', Thrift.MessageType.CALL, this.seqid());" << endl; + f_service_ << + indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() + << "', " << messageType << ", this.seqid());" << endl; } else { - f_service_ << indent() << outputVar << ".writeMessageBegin('" << (*f_iter)->get_name() << "', Thrift.MessageType.CALL, this.seqid);" << endl; + f_service_ << + indent() << outputVar << ".writeMessageBegin('" + << (*f_iter)->get_name() << "', " + << messageType << ", this.seqid);" << endl; } f_service_ << diff --git a/compiler/cpp/src/generate/t_lua_generator.cc b/compiler/cpp/src/generate/t_lua_generator.cc index b7fdad41df5..02467977d46 100644 --- a/compiler/cpp/src/generate/t_lua_generator.cc +++ b/compiler/cpp/src/generate/t_lua_generator.cc @@ -601,8 +601,9 @@ void t_lua_generator::generate_service_client(ofstream &out, indent(out) << endl << "function " << classname << ":send_" << sig << endl; indent_up(); - indent(out) << "self.oprot:writeMessageBegin('" << funcname << - "', TMessageType.CALL, self._seqid)" << endl; + indent(out) << "self.oprot:writeMessageBegin('" << funcname << "', " + << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") + << ", self._seqid)" << endl; indent(out) << "local args = " << funcname << "_args:new{}" << endl; // Set the args diff --git a/compiler/cpp/src/generate/t_ocaml_generator.cc b/compiler/cpp/src/generate/t_ocaml_generator.cc index f3df4e3a4d1..6607f6e5f6e 100644 --- a/compiler/cpp/src/generate/t_ocaml_generator.cc +++ b/compiler/cpp/src/generate/t_ocaml_generator.cc @@ -1105,7 +1105,9 @@ void t_ocaml_generator::generate_service_client(t_service* tservice) { // Serialize the request header f_service_ << - indent() << "oprot#writeMessageBegin (\"" << (*f_iter)->get_name() << "\", Protocol.CALL, seqid);" << endl; + indent() << "oprot#writeMessageBegin (\"" << (*f_iter)->get_name() << "\", " + << ((*f_iter)->is_oneway() ? "Protocol.ONEWAY" : "Protocol.CALL") + << ", seqid);" << endl; f_service_ << indent() << "let args = new " << argsname << " in" << endl; diff --git a/compiler/cpp/src/generate/t_perl_generator.cc b/compiler/cpp/src/generate/t_perl_generator.cc index a40f85bd748..6059ee81936 100644 --- a/compiler/cpp/src/generate/t_perl_generator.cc +++ b/compiler/cpp/src/generate/t_perl_generator.cc @@ -1161,7 +1161,9 @@ void t_perl_generator::generate_service_client(t_service* tservice) { // Serialize the request header f_service_ << - indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType::CALL, $self->{seqid});" << endl; + indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name() << "', " << + ((*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL") << + ", $self->{seqid});" << endl; f_service_ << indent() << "my $args = new " << argsname << "();" << endl; diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc index 9bf1139c572..a787f70ed98 100644 --- a/compiler/cpp/src/generate/t_php_generator.cc +++ b/compiler/cpp/src/generate/t_php_generator.cc @@ -1665,8 +1665,12 @@ void t_php_generator::generate_service_client(t_service* tservice) { indent() << "if ($bin_accel)" << endl; scope_up(f_service_); + string messageType = (*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL"; + f_service_ << - indent() << "thrift_protocol_write_binary($this->output_, '" << (*f_iter)->get_name() << "', " << "TMessageType::CALL, $args, $this->seqid_, $this->output_->isStrictWrite());" << endl; + indent() << "thrift_protocol_write_binary($this->output_, '" + << (*f_iter)->get_name() << "', " << messageType + << ", $args, $this->seqid_, $this->output_->isStrictWrite());" << endl; scope_down(f_service_); f_service_ << @@ -1676,13 +1680,15 @@ void t_php_generator::generate_service_client(t_service* tservice) { // Serialize the request header if (binary_inline_) { f_service_ << - indent() << "$buff = pack('N', (0x80010000 | " << "TMessageType::CALL));" << endl << + indent() << "$buff = pack('N', (0x80010000 | " << messageType + << "));" << endl << indent() << "$buff .= pack('N', strlen('" << funname << "'));" << endl << indent() << "$buff .= '" << funname << "';" << endl << indent() << "$buff .= pack('N', $this->seqid_);" << endl; } else { f_service_ << - indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() << "', " << "TMessageType::CALL, $this->seqid_);" << endl; + indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() << "', " + << messageType << ", $this->seqid_);" << endl; } // Write to the stream diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc index f0c31a4c475..eb558add89e 100644 --- a/compiler/cpp/src/generate/t_py_generator.cc +++ b/compiler/cpp/src/generate/t_py_generator.cc @@ -1344,17 +1344,18 @@ void t_py_generator::generate_service_client(t_service* tservice) { indent_up(); std::string argsname = (*f_iter)->get_name() + "_args"; + std::string messageType = (*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL"; // Serialize the request header if (gen_twisted_ || gen_tornado_) { f_service_ << indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << endl << - indent() << - "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType.CALL, self._seqid)" - << endl; + indent() << "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', " + << messageType << ", self._seqid)" << endl; } else { f_service_ << - indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType.CALL, self._seqid)" << endl; + indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', " + << messageType << ", self._seqid)" << endl; } f_service_ << diff --git a/lib/hs/src/Thrift/Types.hs b/lib/hs/src/Thrift/Types.hs index b014ac63f8f..b90c42c1785 100644 --- a/lib/hs/src/Thrift/Types.hs +++ b/lib/hs/src/Thrift/Types.hs @@ -113,17 +113,20 @@ data MessageType = M_CALL | M_REPLY | M_EXCEPTION + | M_ONEWAY deriving ( Eq, Show ) instance Enum MessageType where fromEnum M_CALL = 1 fromEnum M_REPLY = 2 fromEnum M_EXCEPTION = 3 + fromEnum M_ONEWAY = 4 toEnum 1 = M_CALL toEnum 2 = M_REPLY toEnum 3 = M_EXCEPTION + toEnum 4 = M_ONEWAY toEnum t = error $ "Invalid MessageType " ++ show t instance Arbitrary MessageType where - arbitrary = elements [M_CALL, M_REPLY, M_EXCEPTION] + arbitrary = elements [M_CALL, M_REPLY, M_EXCEPTION, M_ONEWAY] From 356bde5e2e9dc0231406f8c0846ce9386ebeeba8 Mon Sep 17 00:00:00 2001 From: Konrad Grochowski Date: Tue, 16 Sep 2014 22:50:30 +0200 Subject: [PATCH 4/4] THRIFT-2704 - oneway support more fixes --- doc/specs/thrift-protocol-spec.md | 2 +- lib/cpp/src/thrift/processor/PeekProcessor.cpp | 2 +- lib/cpp/src/thrift/processor/StatsProcessor.h | 2 +- lib/cpp/test/AllProtocolTests.tcc | 6 ++++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/specs/thrift-protocol-spec.md b/doc/specs/thrift-protocol-spec.md index 24d83f68193..48ee8273dee 100644 --- a/doc/specs/thrift-protocol-spec.md +++ b/doc/specs/thrift-protocol-spec.md @@ -43,7 +43,7 @@ of a function, or an exception. ::= STRING - ::= T_CALL | T_REPLY | T_EXCEPTION + ::= T_CALL | T_REPLY | T_EXCEPTION | T_ONEWAY ::= I32 diff --git a/lib/cpp/src/thrift/processor/PeekProcessor.cpp b/lib/cpp/src/thrift/processor/PeekProcessor.cpp index bfc4ac73ffd..9303a13c7c5 100644 --- a/lib/cpp/src/thrift/processor/PeekProcessor.cpp +++ b/lib/cpp/src/thrift/processor/PeekProcessor.cpp @@ -66,7 +66,7 @@ bool PeekProcessor::process(boost::shared_ptr in, int32_t seqid; in->readMessageBegin(fname, mtype, seqid); - if (mtype != T_CALL) { + if (mtype != T_CALL && mtype != T_ONEWAY) { throw TException("Unexpected message type"); } diff --git a/lib/cpp/src/thrift/processor/StatsProcessor.h b/lib/cpp/src/thrift/processor/StatsProcessor.h index 58cd1dc5d84..0fc123ea807 100644 --- a/lib/cpp/src/thrift/processor/StatsProcessor.h +++ b/lib/cpp/src/thrift/processor/StatsProcessor.h @@ -50,7 +50,7 @@ class StatsProcessor : public apache::thrift::TProcessor { int32_t seqid; piprot_->readMessageBegin(fname, mtype, seqid); - if (mtype != apache::thrift::protocol::T_CALL) { + if (mtype != apache::thrift::protocol::T_CALL && mtype != apache::thrift::protocol::T_ONEWAY) { if (print_) { printf("Unknown message type\n"); } diff --git a/lib/cpp/test/AllProtocolTests.tcc b/lib/cpp/test/AllProtocolTests.tcc index 7ccaef5b224..3c98943418f 100644 --- a/lib/cpp/test/AllProtocolTests.tcc +++ b/lib/cpp/test/AllProtocolTests.tcc @@ -97,14 +97,16 @@ void testMessage() { const char* name; TMessageType type; int32_t seqid; - } messages[4] = { + } messages[] = { {"short message name", T_CALL, 0}, {"1", T_REPLY, 12345}, {"loooooooooooooooooooooooooooooooooong", T_EXCEPTION, 1 << 16}, + {"one way push", T_ONEWAY, 12}, {"Janky", T_CALL, 0} }; + const int messages_count = sizeof(messages) / sizeof(TMessage); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < messages_count; i++) { shared_ptr transport(new TMemoryBuffer()); shared_ptr protocol(new TProto(transport));