You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by br...@apache.org on 2011/03/02 19:25:24 UTC

svn commit: r1076318 - /thrift/trunk/lib/erl/src/thrift_processor.erl

Author: bryanduxbury
Date: Wed Mar  2 18:25:24 2011
New Revision: 1076318

URL: http://svn.apache.org/viewvc?rev=1076318&view=rev
Log:
THRIFT-1076. erl: Erlang Thrift socket server has a bug that causes java thrift client of framed binary client to throw 'out of sequence' exception

This patch makes the erlang server return the seq id that the client sent instead of 0.

Patch: Pascal Qu

Modified:
    thrift/trunk/lib/erl/src/thrift_processor.erl

Modified: thrift/trunk/lib/erl/src/thrift_processor.erl
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/erl/src/thrift_processor.erl?rev=1076318&r1=1076317&r2=1076318&view=diff
==============================================================================
--- thrift/trunk/lib/erl/src/thrift_processor.erl (original)
+++ thrift/trunk/lib/erl/src/thrift_processor.erl Wed Mar  2 18:25:24 2011
@@ -37,12 +37,14 @@ loop(State0 = #thrift_processor{protocol
     State1 = State0#thrift_processor{protocol = Proto1},
     case MessageBegin of
         #protocol_message_begin{name = Function,
-                                type = ?tMessageType_CALL} ->
-            {State2, ok} = handle_function(State1, list_to_atom(Function)),
+                                type = ?tMessageType_CALL,
+                                seqid = Seqid} ->
+            {State2, ok} = handle_function(State1, list_to_atom(Function), Seqid),
             loop(State2);
         #protocol_message_begin{name = Function,
-                                type = ?tMessageType_ONEWAY} ->
-            {State2, ok} = handle_function(State1, list_to_atom(Function)),
+                                type = ?tMessageType_ONEWAY, 
+                                seqid = Seqid} ->
+            {State2, ok} = handle_function(State1, list_to_atom(Function), Seqid),
             loop(State2);
         {error, timeout} ->
             thrift_protocol:close_transport(Proto1),
@@ -56,7 +58,8 @@ loop(State0 = #thrift_processor{protocol
 handle_function(State0=#thrift_processor{protocol = Proto0,
                                          handler = Handler,
                                          service = Service},
-                Function) ->
+                Function,
+                Seqid) ->
     InParams = Service:function_info(Function, params_type),
 
     {Proto1, {ok, Params}} = thrift_protocol:read(Proto0, InParams),
@@ -67,14 +70,14 @@ handle_function(State0=#thrift_processor
         %% {Micro, Result} = better_timer(Handler, handle_function, [Function, Params]),
         %% error_logger:info_msg("Processed ~p(~p) in ~.4fms~n",
         %%                       [Function, Params, Micro/1000.0]),
-        handle_success(State1, Function, Result)
+        handle_success(State1, Function, Result, Seqid)
     catch
         Type:Data when Type =:= throw orelse Type =:= error ->
-            handle_function_catch(State1, Function, Type, Data)
+            handle_function_catch(State1, Function, Type, Data, Seqid)
     end.
 
 handle_function_catch(State = #thrift_processor{service = Service},
-                      Function, ErrType, ErrData) ->
+                      Function, ErrType, ErrData, Seqid) ->
     IsOneway = Service:function_info(Function, reply_type) =:= oneway_void,
 
     case {ErrType, ErrData} of
@@ -87,26 +90,27 @@ handle_function_catch(State = #thrift_pr
 
         {throw, Exception} when is_tuple(Exception), size(Exception) > 0 ->
             %error_logger:warning_msg("~p threw exception: ~p~n", [Function, Exception]),
-            handle_exception(State, Function, Exception);
+            handle_exception(State, Function, Exception, Seqid);
             % we still want to accept more requests from this client
 
         {error, Error} ->
-            handle_error(State, Function, Error)
+            handle_error(State, Function, Error, Seqid)
     end.
 
 handle_success(State = #thrift_processor{service = Service},
                Function,
-               Result) ->
+               Result,
+               Seqid) ->
     ReplyType  = Service:function_info(Function, reply_type),
     StructName = atom_to_list(Function) ++ "_result",
 
     case Result of
         {reply, ReplyData} ->
             Reply = {{struct, [{0, ReplyType}]}, {StructName, ReplyData}},
-            send_reply(State, Function, ?tMessageType_REPLY, Reply);
+            send_reply(State, Function, ?tMessageType_REPLY, Reply, Seqid);
 
         ok when ReplyType == {struct, []} ->
-            send_reply(State, Function, ?tMessageType_REPLY, {ReplyType, {StructName}});
+            send_reply(State, Function, ?tMessageType_REPLY, {ReplyType, {StructName}}, Seqid);
 
         ok when ReplyType == oneway_void ->
             %% no reply for oneway void
@@ -115,7 +119,8 @@ handle_success(State = #thrift_processor
 
 handle_exception(State = #thrift_processor{service = Service},
                  Function,
-                 Exception) ->
+                 Exception,
+                 Seqid) ->
     ExceptionType = element(1, Exception),
     %% Fetch a structure like {struct, [{-2, {struct, {Module, Type}}},
     %%                                  {-3, {struct, {Module, Type}}}]}
@@ -138,20 +143,20 @@ handle_exception(State = #thrift_process
                                                 % Make sure we got at least one defined
     case lists:all(fun(X) -> X =:= undefined end, ExceptionList) of
         true ->
-            handle_unknown_exception(State, Function, Exception);
+            handle_unknown_exception(State, Function, Exception, Seqid);
         false ->
-            send_reply(State, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple})
+            send_reply(State, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple}, Seqid)
     end.
 
 %%
 %% Called when an exception has been explicitly thrown by the service, but it was
 %% not one of the exceptions that was defined for the function.
 %%
-handle_unknown_exception(State, Function, Exception) ->
+handle_unknown_exception(State, Function, Exception, Seqid) ->
     handle_error(State, Function, {exception_not_declared_as_thrown,
-                                   Exception}).
+                                   Exception}, Seqid).
 
-handle_error(State, Function, Error) ->
+handle_error(State, Function, Error, Seqid) ->
     Stack = erlang:get_stacktrace(),
     error_logger:error_msg("~p had an error: ~p~n", [Function, {Error, Stack}]),
 
@@ -167,13 +172,13 @@ handle_error(State, Function, Error) ->
              #'TApplicationException'{
                 message = Message,
                 type = ?TApplicationException_UNKNOWN}},
-    send_reply(State, Function, ?tMessageType_EXCEPTION, Reply).
+    send_reply(State, Function, ?tMessageType_EXCEPTION, Reply, Seqid).
 
-send_reply(State = #thrift_processor{protocol = Proto0}, Function, ReplyMessageType, Reply) ->
+send_reply(State = #thrift_processor{protocol = Proto0}, Function, ReplyMessageType, Reply, Seqid) ->
     {Proto1, ok} = thrift_protocol:write(Proto0, #protocol_message_begin{
                                            name = atom_to_list(Function),
                                            type = ReplyMessageType,
-                                           seqid = 0}),
+                                           seqid = Seqid}),
     {Proto2, ok} = thrift_protocol:write(Proto1, Reply),
     {Proto3, ok} = thrift_protocol:write(Proto2, message_end),
     {Proto4, ok} = thrift_protocol:flush_transport(Proto3),