[thrift] handle timeouts and other errors gracefully (Erlang)
Reviewed By: iproctor
Test Plan: tutorial, channel
Revert Plan: ok
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665190 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/erl/lib/thrift/src/tErlProcessor.erl b/lib/erl/lib/thrift/src/tErlProcessor.erl
index ec263e3..a6d1073 100644
--- a/lib/erl/lib/thrift/src/tErlProcessor.erl
+++ b/lib/erl/lib/thrift/src/tErlProcessor.erl
@@ -60,4 +60,4 @@
GP = oop:get(This, generatedProcessor),
Handler = oop:get(This, handler),
- apply(GP, process, [Handler, Iprot, Oprot]).
+ GP:process(Handler, Iprot, Oprot).
diff --git a/lib/erl/lib/thrift/src/thrift_logger.erl b/lib/erl/lib/thrift/src/thrift_logger.erl
index 286d40d..82ba772 100644
--- a/lib/erl/lib/thrift/src/thrift_logger.erl
+++ b/lib/erl/lib/thrift/src/thrift_logger.erl
@@ -138,7 +138,8 @@
[Pid, LastMessage, Obj, Reason] = Data,
%% TODO: move as much logic as possible out of thrift_logger
- Ignore = error /= thrift_utils:unnest_record(Reason, tTransportException),
+ Ignore = (is_tuple(Reason) andalso size(Reason) >= 1 andalso element(1, Reason) == timeout)
+ orelse error /= thrift_utils:unnest_record(Reason, tTransportException),
case Ignore of
true ->
@@ -216,6 +217,9 @@
handle_thrift_info(conn_accepted, {AddrString}, State) ->
sformat("connection accepted from ~s", [AddrString]);
+handle_thrift_info(conn_timeout, {AddrString}, State) ->
+ sformat("connection timed out from ~s", [AddrString]);
+
handle_thrift_info(conn_closed, {AddrString}, State) ->
sformat("connection closed from ~s", [AddrString]);
diff --git a/lib/erl/lib/thrift/src/transport/tErlAcceptor.erl b/lib/erl/lib/thrift/src/transport/tErlAcceptor.erl
index 8093e00..f3308cf 100644
--- a/lib/erl/lib/thrift/src/transport/tErlAcceptor.erl
+++ b/lib/erl/lib/thrift/src/transport/tErlAcceptor.erl
@@ -89,10 +89,14 @@
%% start_new(, ...)
Processor = oop:start_new(tErlProcessor, [GP, Handler]), %% TODO
- receive_loop(This, Processor, Prot, Prot),
-
- ?INFO(conn_closed, {AddrString}),
-
+ case receive_loop(This, Processor, Prot, Prot) of
+ conn_timeout ->
+ ?INFO(conn_timeout, {AddrString});
+ conn_closed ->
+ ?INFO(conn_closed, {AddrString});
+ {Class, Else} ->
+ ?ERROR("unhandled ~p in tErlAcceptor: ~p", [Class, Else])
+ end,
exit(normal);
Else ->
@@ -110,15 +114,19 @@
?INFO(req_processed, {Value}),
receive_loop(This, Processor, Iprot, Oprot)
catch
- %% the following clause must be last because we might reexit
+ exit:{timeout, _} ->
+ conn_timeout;
+
+ %% the following clause must be last
+ %% cpiro: would be best to implement an is_a/2 guard BIF
%% cpiro: breaks if it's a subclass of tTransportException
%% since unnest_record knows nothing about oop
- exit:Else ->
+ Class:Else ->
case thrift_utils:unnest_record(Else, tTransportException) of
{ok, TTE} when TTE#tTransportException.type == ?tTransportException_NOT_OPEN ->
- ok; %% will exit to tErlAcceptor
+ conn_closed;
_ ->
- exit(Else) %% shouldn't have caught it in the first place
+ {Class, Else}
end
end.