diff options
author | alisdair sullivan <alisdairsullivan@yahoo.ca> | 2014-09-30 22:03:34 -0700 |
---|---|---|
committer | Nobuaki Sukegawa <nsuke@apache.org> | 2015-11-01 18:07:15 +0900 |
commit | 7bdba5c06a7aa40cf83352c214270a2f1f4dd572 (patch) | |
tree | b888720570094586aac65d681049bd53ba36715d /lib/erl | |
parent | 149ecc1a5fff2f68d413df730b97cc7272813077 (diff) | |
download | thrift-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.erl | 71 |
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) -> |