summaryrefslogtreecommitdiff
path: root/lib/erl
diff options
context:
space:
mode:
authoralisdair sullivan <alisdairsullivan@yahoo.ca>2014-09-30 22:03:34 -0700
committerNobuaki Sukegawa <nsuke@apache.org>2015-11-01 18:07:15 +0900
commit7bdba5c06a7aa40cf83352c214270a2f1f4dd572 (patch)
treeb888720570094586aac65d681049bd53ba36715d /lib/erl
parent149ecc1a5fff2f68d413df730b97cc7272813077 (diff)
downloadthrift-7bdba5c06a7aa40cf83352c214270a2f1f4dd572.tar.gz
THRIFT-2708 add support for oneway (async) function calls in erlang client
Client: Erlang Patch: Alisdair Sullivan modified by Nobuaki Sukegawa Modification: Fix invalid send_call return type. This closes #231
Diffstat (limited to 'lib/erl')
-rw-r--r--lib/erl/src/thrift_client.erl71
1 files changed, 39 insertions, 32 deletions
diff --git a/lib/erl/src/thrift_client.erl b/lib/erl/src/thrift_client.erl
index ff5c3dcdd..209bd4c15 100644
--- a/lib/erl/src/thrift_client.erl
+++ b/lib/erl/src/thrift_client.erl
@@ -36,13 +36,11 @@ new(Protocol, Service)
-spec call(#tclient{}, atom(), list()) -> {#tclient{}, {ok, any()} | {error, any()}}.
call(Client = #tclient{}, Function, Args)
- when is_atom(Function), is_list(Args) ->
- case send_function_call(Client, Function, Args) of
- {Client1, ok} ->
- receive_function_result(Client1, Function);
- Else ->
- Else
- end.
+when is_atom(Function), is_list(Args) ->
+ case send_function_call(Client, Function, Args) of
+ {ok, Client1} -> receive_function_result(Client1, Function);
+ Else -> Else
+ end.
%% Sends a function call but does not read the result. This is useful
@@ -51,7 +49,10 @@ call(Client = #tclient{}, Function, Args)
-spec send_call(#tclient{}, atom(), list()) -> {#tclient{}, ok}.
send_call(Client = #tclient{}, Function, Args)
when is_atom(Function), is_list(Args) ->
- send_function_call(Client, Function, Args).
+ case send_function_call(Client, Function, Args) of
+ {ok, Client1} -> {Client1, ok};
+ Else -> Else
+ end.
-spec close(#tclient{}) -> ok.
close(#tclient{protocol=Protocol}) ->
@@ -61,30 +62,36 @@ close(#tclient{protocol=Protocol}) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
--spec send_function_call(#tclient{}, atom(), list()) -> {#tclient{}, ok | {error, any()}}.
-send_function_call(Client = #tclient{protocol = Proto0,
- service = Service,
- seqid = SeqId},
- Function,
- Args) ->
- Params = try Service:function_info(Function, params_type)
- catch error:function_clause -> no_function
- end,
- case Params of
- no_function ->
- {Client, {error, {no_function, Function}}};
- {struct, PList} when length(PList) =/= length(Args) ->
- {Client, {error, {bad_args, Function, Args}}};
- {struct, _PList} ->
- Begin = #protocol_message_begin{name = atom_to_list(Function),
- type = ?tMessageType_CALL,
- seqid = SeqId},
- {Proto1, ok} = thrift_protocol:write(Proto0, Begin),
- {Proto2, ok} = thrift_protocol:write(Proto1, {Params, list_to_tuple([Function | Args])}),
- {Proto3, ok} = thrift_protocol:write(Proto2, message_end),
- {Proto4, ok} = thrift_protocol:flush_transport(Proto3),
- {Client#tclient{protocol = Proto4}, ok}
- end.
+-spec send_function_call(#tclient{}, atom(), list()) -> {sync | async | {error, any()}, #tclient{}}.
+send_function_call(Client = #tclient{service = Service}, Function, Args) ->
+ {Params, Reply} = try
+ {Service:function_info(Function, params_type), Service:function_info(Function, reply_type)}
+ catch error:function_clause -> no_function
+ end,
+ MsgType = case Reply of
+ oneway_void -> ?tMessageType_ONEWAY;
+ _ -> ?tMessageType_CALL
+ end,
+ case Params of
+ no_function ->
+ {{error, {no_function, Function}}, Client};
+ {struct, PList} when length(PList) =/= length(Args) ->
+ {{error, {bad_args, Function, Args}}, Client};
+ {struct, _PList} -> write_message(Client, Function, Args, Params, MsgType)
+ end.
+
+-spec write_message(#tclient{}, atom(), list(), {struct, list()}, integer()) ->
+ {ok, #tclient{}}.
+write_message(Client = #tclient{protocol = P0, seqid = Seq}, Function, Args, Params, MsgType) ->
+ {P1, ok} = thrift_protocol:write(P0, #protocol_message_begin{
+ name = atom_to_list(Function),
+ type = MsgType,
+ seqid = Seq
+ }),
+ {P2, ok} = thrift_protocol:write(P1, {Params, list_to_tuple([Function|Args])}),
+ {P3, ok} = thrift_protocol:write(P2, message_end),
+ {P4, ok} = thrift_protocol:flush_transport(P3),
+ {ok, Client#tclient{protocol = P4}}.
-spec receive_function_result(#tclient{}, atom()) -> {#tclient{}, {ok, any()} | {error, any()}}.
receive_function_result(Client = #tclient{service = Service}, Function) ->