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 2010/08/19 07:06:04 UTC
svn commit: r987018 [2/2] - in /incubator/thrift/trunk:
compiler/cpp/src/generate/ lib/erl/ lib/erl/build/ lib/erl/include/
lib/erl/src/ test/erl/ test/erl/src/ tutorial/erl/
Modified: incubator/thrift/trunk/lib/erl/src/thrift_processor.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_processor.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_processor.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_processor.erl Thu Aug 19 05:06:02 2010
@@ -24,55 +24,54 @@
-include("thrift_constants.hrl").
-include("thrift_protocol.hrl").
--record(thrift_processor, {handler, in_protocol, out_protocol, service}).
+-record(thrift_processor, {handler, protocol, service}).
-init({Server, ProtoGen, Service, Handler}) when is_function(ProtoGen, 0) ->
- {ok, IProt, OProt} = ProtoGen(),
- loop(#thrift_processor{in_protocol = IProt,
- out_protocol = OProt,
+init({_Server, ProtoGen, Service, Handler}) when is_function(ProtoGen, 0) ->
+ {ok, Proto} = ProtoGen(),
+ loop(#thrift_processor{protocol = Proto,
service = Service,
handler = Handler}).
-loop(State = #thrift_processor{in_protocol = IProto,
- out_protocol = OProto}) ->
- case thrift_protocol:read(IProto, message_begin) of
+loop(State0 = #thrift_processor{protocol = Proto0}) ->
+ {Proto1, MessageBegin} = thrift_protocol:read(Proto0, message_begin),
+ State1 = State0#thrift_processor{protocol = Proto1},
+ case MessageBegin of
#protocol_message_begin{name = Function,
type = ?tMessageType_CALL} ->
- ok = handle_function(State, list_to_atom(Function)),
- loop(State);
+ {State2, ok} = handle_function(State1, list_to_atom(Function)),
+ loop(State2);
#protocol_message_begin{name = Function,
type = ?tMessageType_ONEWAY} ->
- ok = handle_function(State, list_to_atom(Function)),
- loop(State);
+ {State2, ok} = handle_function(State1, list_to_atom(Function)),
+ loop(State2);
{error, timeout} ->
- thrift_protocol:close_transport(OProto),
+ thrift_protocol:close_transport(Proto1),
ok;
{error, closed} ->
%% error_logger:info_msg("Client disconnected~n"),
- thrift_protocol:close_transport(OProto),
+ thrift_protocol:close_transport(Proto1),
exit(shutdown)
end.
-handle_function(State=#thrift_processor{in_protocol = IProto,
- out_protocol = OProto,
- handler = Handler,
- service = Service},
+handle_function(State0=#thrift_processor{protocol = Proto0,
+ handler = Handler,
+ service = Service},
Function) ->
InParams = Service:function_info(Function, params_type),
- {ok, Params} = thrift_protocol:read(IProto, InParams),
+ {Proto1, {ok, Params}} = thrift_protocol:read(Proto0, InParams),
+ State1 = State0#thrift_processor{protocol = Proto1},
try
Result = Handler:handle_function(Function, Params),
%% {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(State, Function, Result)
+ handle_success(State1, Function, Result)
catch
- Type:Data ->
- handle_function_catch(State, Function, Type, Data)
- end,
- after_reply(OProto).
+ Type:Data when Type =:= throw orelse Type =:= error ->
+ handle_function_catch(State1, Function, Type, Data)
+ end.
handle_function_catch(State = #thrift_processor{service = Service},
Function, ErrType, ErrData) ->
@@ -84,39 +83,37 @@ handle_function_catch(State = #thrift_pr
error_logger:warning_msg(
"oneway void ~p threw error which must be ignored: ~p",
[Function, {ErrType, ErrData, Stack}]),
- ok;
+ {State, ok};
{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),
- ok; % we still want to accept more requests from this client
+ %error_logger:warning_msg("~p threw exception: ~p~n", [Function, Exception]),
+ handle_exception(State, Function, Exception);
+ % we still want to accept more requests from this client
{error, Error} ->
- ok = handle_error(State, Function, Error)
+ handle_error(State, Function, Error)
end.
-handle_success(State = #thrift_processor{out_protocol = OProto,
- service = Service},
+handle_success(State = #thrift_processor{service = Service},
Function,
Result) ->
ReplyType = Service:function_info(Function, reply_type),
StructName = atom_to_list(Function) ++ "_result",
- ok = case Result of
- {reply, ReplyData} ->
- Reply = {{struct, [{0, ReplyType}]}, {StructName, ReplyData}},
- send_reply(OProto, Function, ?tMessageType_REPLY, Reply);
-
- ok when ReplyType == {struct, []} ->
- send_reply(OProto, Function, ?tMessageType_REPLY, {ReplyType, {StructName}});
-
- ok when ReplyType == oneway_void ->
- %% no reply for oneway void
- ok
- end.
+ case Result of
+ {reply, ReplyData} ->
+ Reply = {{struct, [{0, ReplyType}]}, {StructName, ReplyData}},
+ send_reply(State, Function, ?tMessageType_REPLY, Reply);
+
+ ok when ReplyType == {struct, []} ->
+ send_reply(State, Function, ?tMessageType_REPLY, {ReplyType, {StructName}});
+
+ ok when ReplyType == oneway_void ->
+ %% no reply for oneway void
+ {State, ok}
+ end.
-handle_exception(State = #thrift_processor{out_protocol = OProto,
- service = Service},
+handle_exception(State = #thrift_processor{service = Service},
Function,
Exception) ->
ExceptionType = element(1, Exception),
@@ -141,9 +138,9 @@ handle_exception(State = #thrift_process
% Make sure we got at least one defined
case lists:all(fun(X) -> X =:= undefined end, ExceptionList) of
true ->
- ok = handle_unknown_exception(State, Function, Exception);
+ handle_unknown_exception(State, Function, Exception);
false ->
- ok = send_reply(OProto, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple})
+ send_reply(State, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple})
end.
%%
@@ -154,7 +151,7 @@ handle_unknown_exception(State, Function
handle_error(State, Function, {exception_not_declared_as_thrown,
Exception}).
-handle_error(#thrift_processor{out_protocol = OProto}, Function, Error) ->
+handle_error(State, Function, Error) ->
Stack = erlang:get_stacktrace(),
error_logger:error_msg("~p had an error: ~p~n", [Function, {Error, Stack}]),
@@ -170,19 +167,14 @@ handle_error(#thrift_processor{out_proto
#'TApplicationException'{
message = Message,
type = ?TApplicationException_UNKNOWN}},
- send_reply(OProto, Function, ?tMessageType_EXCEPTION, Reply).
+ send_reply(State, Function, ?tMessageType_EXCEPTION, Reply).
-send_reply(OProto, Function, ReplyMessageType, Reply) ->
- ok = thrift_protocol:write(OProto, #protocol_message_begin{
- name = atom_to_list(Function),
- type = ReplyMessageType,
- seqid = 0}),
- ok = thrift_protocol:write(OProto, Reply),
- ok = thrift_protocol:write(OProto, message_end),
- ok = thrift_protocol:flush_transport(OProto),
- ok.
-
-after_reply(OProto) ->
- ok = thrift_protocol:flush_transport(OProto)
- %% ok = thrift_protocol:close_transport(OProto)
- .
+send_reply(State = #thrift_processor{protocol = Proto0}, Function, ReplyMessageType, Reply) ->
+ {Proto1, ok} = thrift_protocol:write(Proto0, #protocol_message_begin{
+ name = atom_to_list(Function),
+ type = ReplyMessageType,
+ seqid = 0}),
+ {Proto2, ok} = thrift_protocol:write(Proto1, Reply),
+ {Proto3, ok} = thrift_protocol:write(Proto2, message_end),
+ {Proto4, ok} = thrift_protocol:flush_transport(Proto3),
+ {State#thrift_processor{protocol = Proto4}, ok}.
Modified: incubator/thrift/trunk/lib/erl/src/thrift_protocol.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_protocol.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_protocol.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_protocol.erl Thu Aug 19 05:06:02 2010
@@ -49,10 +49,13 @@ new(Module, Data) when is_atom(Module) -
{ok, #protocol{module = Module,
data = Data}}.
-flush_transport(#protocol{module = Module,
- data = Data}) ->
- Module:flush_transport(Data).
+-spec flush_transport(#protocol{}) -> {#protocol{}, ok}.
+flush_transport(Proto = #protocol{module = Module,
+ data = Data}) ->
+ {NewData, Result} = Module:flush_transport(Data),
+ {Proto#protocol{data = NewData}, Result}.
+-spec close_transport(#protocol{}) -> ok.
close_transport(#protocol{module = Module,
data = Data}) ->
Module:close_transport(Data).
@@ -86,7 +89,8 @@ term_to_typeid({list, _}) -> ?tType_LIST
%% Structure is like:
%% [{Fid, Type}, ...]
-read(IProto, {struct, Structure}, Tag)
+-spec read(#protocol{}, {struct, _StructDef}, atom()) -> {#protocol{}, {ok, tuple()}}.
+read(IProto0, {struct, Structure}, Tag)
when is_list(Structure), is_atom(Tag) ->
% If we want a tagged tuple, we need to offset all the tuple indices
@@ -103,14 +107,23 @@ read(IProto, {struct, Structure}, Tag)
% Fid -> {Type, Index}
SDict = dict:from_list(SWithIndices),
- ok = read(IProto, struct_begin),
+ {IProto1, ok} = read(IProto0, struct_begin),
RTuple0 = erlang:make_tuple(length(Structure) + Offset, undefined),
RTuple1 = if Tag =/= undefined -> setelement(1, RTuple0, Tag);
true -> RTuple0
end,
- RTuple2 = read_struct_loop(IProto, SDict, RTuple1),
- {ok, RTuple2}.
+ {IProto2, RTuple2} = read_struct_loop(IProto1, SDict, RTuple1),
+ {IProto2, {ok, RTuple2}}.
+
+
+%% NOTE: Keep this in sync with thrift_protocol_behaviour:read
+-spec read
+ (#protocol{}, {struct, _Info}) -> {#protocol{}, {ok, tuple()} | {error, _Reason}};
+ (#protocol{}, tprot_cont_tag()) -> {#protocol{}, {ok, term()} | {error, _Reason}};
+ (#protocol{}, tprot_empty_tag()) -> {#protocol{}, ok | {error, _Reason}};
+ (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}};
+ (#protocol{}, tprot_data_tag()) -> {#protocol{}, {ok, term()} | {error, _Reason}}.
read(IProto, {struct, {Module, StructureName}}) when is_atom(Module),
is_atom(StructureName) ->
@@ -119,137 +132,165 @@ read(IProto, {struct, {Module, Structure
read(IProto, S={struct, Structure}) when is_list(Structure) ->
read(IProto, S, undefined);
-read(IProto, {list, Type}) ->
- #protocol_list_begin{etype = EType, size = Size} =
- read(IProto, list_begin),
- List = [Result || {ok, Result} <-
- [read(IProto, Type) || _X <- lists:duplicate(Size, 0)]],
- ok = read(IProto, list_end),
- {ok, List};
-
-read(IProto, {map, KeyType, ValType}) ->
- #protocol_map_begin{size = Size} =
- read(IProto, map_begin),
-
- List = [{Key, Val} || {{ok, Key}, {ok, Val}} <-
- [{read(IProto, KeyType),
- read(IProto, ValType)} || _X <- lists:duplicate(Size, 0)]],
- ok = read(IProto, map_end),
- {ok, dict:from_list(List)};
-
-read(IProto, {set, Type}) ->
- #protocol_set_begin{etype = _EType,
- size = Size} =
- read(IProto, set_begin),
- List = [Result || {ok, Result} <-
- [read(IProto, Type) || _X <- lists:duplicate(Size, 0)]],
- ok = read(IProto, set_end),
- {ok, sets:from_list(List)};
-
-read(#protocol{module = Module,
- data = ModuleData}, ProtocolType) ->
- Module:read(ModuleData, ProtocolType).
-
-read_struct_loop(IProto, SDict, RTuple) ->
- #protocol_field_begin{type = FType, id = Fid, name = Name} =
- thrift_protocol:read(IProto, field_begin),
+read(IProto0, {list, Type}) ->
+ {IProto1, #protocol_list_begin{etype = EType, size = Size}} =
+ read(IProto0, list_begin),
+ {EType, EType} = {term_to_typeid(Type), EType},
+ {List, IProto2} = lists:mapfoldl(fun(_, ProtoS0) ->
+ {ProtoS1, {ok, Item}} = read(ProtoS0, Type),
+ {Item, ProtoS1}
+ end,
+ IProto1,
+ lists:duplicate(Size, 0)),
+ {IProto3, ok} = read(IProto2, list_end),
+ {IProto3, {ok, List}};
+
+read(IProto0, {map, KeyType, ValType}) ->
+ {IProto1, #protocol_map_begin{size = Size, ktype = KType, vtype = VType}} =
+ read(IProto0, map_begin),
+ {KType, KType} = {term_to_typeid(KeyType), KType},
+ {VType, VType} = {term_to_typeid(ValType), VType},
+ {List, IProto2} = lists:mapfoldl(fun(_, ProtoS0) ->
+ {ProtoS1, {ok, Key}} = read(ProtoS0, KeyType),
+ {ProtoS2, {ok, Val}} = read(ProtoS1, ValType),
+ {{Key, Val}, ProtoS2}
+ end,
+ IProto1,
+ lists:duplicate(Size, 0)),
+ {IProto3, ok} = read(IProto2, map_end),
+ {IProto3, {ok, dict:from_list(List)}};
+
+read(IProto0, {set, Type}) ->
+ {IProto1, #protocol_set_begin{etype = EType, size = Size}} =
+ read(IProto0, set_begin),
+ {EType, EType} = {term_to_typeid(Type), EType},
+ {List, IProto2} = lists:mapfoldl(fun(_, ProtoS0) ->
+ {ProtoS1, {ok, Item}} = read(ProtoS0, Type),
+ {Item, ProtoS1}
+ end,
+ IProto1,
+ lists:duplicate(Size, 0)),
+ {IProto3, ok} = read(IProto2, set_end),
+ {IProto3, {ok, sets:from_list(List)}};
+
+read(Protocol, ProtocolType) ->
+ read_specific(Protocol, ProtocolType).
+
+%% NOTE: Keep this in sync with thrift_protocol_behaviour:read
+-spec read_specific
+ (#protocol{}, tprot_empty_tag()) -> {#protocol{}, ok | {error, _Reason}};
+ (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}};
+ (#protocol{}, tprot_data_tag()) -> {#protocol{}, {ok, term()} | {error, _Reason}}.
+read_specific(Proto = #protocol{module = Module,
+ data = ModuleData}, ProtocolType) ->
+ {NewData, Result} = Module:read(ModuleData, ProtocolType),
+ {Proto#protocol{data = NewData}, Result}.
+
+read_struct_loop(IProto0, SDict, RTuple) ->
+ {IProto1, #protocol_field_begin{type = FType, id = Fid}} =
+ thrift_protocol:read(IProto0, field_begin),
case {FType, Fid} of
{?tType_STOP, _} ->
- RTuple;
+ {IProto1, RTuple};
_Else ->
case dict:find(Fid, SDict) of
{ok, {Type, Index}} ->
case term_to_typeid(Type) of
FType ->
- {ok, Val} = read(IProto, Type),
- thrift_protocol:read(IProto, field_end),
+ {IProto2, {ok, Val}} = read(IProto1, Type),
+ {IProto3, ok} = thrift_protocol:read(IProto2, field_end),
NewRTuple = setelement(Index, RTuple, Val),
- read_struct_loop(IProto, SDict, NewRTuple);
+ read_struct_loop(IProto3, SDict, NewRTuple);
Expected ->
error_logger:info_msg(
"Skipping field ~p with wrong type (~p != ~p)~n",
[Fid, FType, Expected]),
- skip_field(FType, IProto, SDict, RTuple)
+ skip_field(FType, IProto1, SDict, RTuple)
end;
_Else2 ->
error_logger:info_msg("Skipping field ~p with unknown fid~n", [Fid]),
- skip_field(FType, IProto, SDict, RTuple)
+ skip_field(FType, IProto1, SDict, RTuple)
end
end.
-skip_field(FType, IProto, SDict, RTuple) ->
+skip_field(FType, IProto0, SDict, RTuple) ->
FTypeAtom = thrift_protocol:typeid_to_atom(FType),
- thrift_protocol:skip(IProto, FTypeAtom),
- read(IProto, field_end),
- read_struct_loop(IProto, SDict, RTuple).
-
-
-skip(Proto, struct) ->
- ok = read(Proto, struct_begin),
- ok = skip_struct_loop(Proto),
- ok = read(Proto, struct_end);
-
-skip(Proto, map) ->
- Map = read(Proto, map_begin),
- ok = skip_map_loop(Proto, Map),
- ok = read(Proto, map_end);
-
-skip(Proto, set) ->
- Set = read(Proto, set_begin),
- ok = skip_set_loop(Proto, Set),
- ok = read(Proto, set_end);
-
-skip(Proto, list) ->
- List = read(Proto, list_begin),
- ok = skip_list_loop(Proto, List),
- ok = read(Proto, list_end);
-
-skip(Proto, Type) when is_atom(Type) ->
- _Ignore = read(Proto, Type),
- ok.
+ {IProto1, ok} = thrift_protocol:skip(IProto0, FTypeAtom),
+ {IProto2, ok} = read(IProto1, field_end),
+ read_struct_loop(IProto2, SDict, RTuple).
+
+-spec skip(#protocol{}, term()) -> {#protocol{}, ok}.
+
+skip(Proto0, struct) ->
+ {Proto1, ok} = read(Proto0, struct_begin),
+ {Proto2, ok} = skip_struct_loop(Proto1),
+ {Proto3, ok} = read(Proto2, struct_end),
+ {Proto3, ok};
+
+skip(Proto0, map) ->
+ {Proto1, Map} = read(Proto0, map_begin),
+ {Proto2, ok} = skip_map_loop(Proto1, Map),
+ {Proto3, ok} = read(Proto2, map_end),
+ {Proto3, ok};
+
+skip(Proto0, set) ->
+ {Proto1, Set} = read(Proto0, set_begin),
+ {Proto2, ok} = skip_set_loop(Proto1, Set),
+ {Proto3, ok} = read(Proto2, set_end),
+ {Proto3, ok};
+
+skip(Proto0, list) ->
+ {Proto1, List} = read(Proto0, list_begin),
+ {Proto2, ok} = skip_list_loop(Proto1, List),
+ {Proto3, ok} = read(Proto2, list_end),
+ {Proto3, ok};
+
+skip(Proto0, Type) when is_atom(Type) ->
+ {Proto1, _Ignore} = read(Proto0, Type),
+ {Proto1, ok}.
-skip_struct_loop(Proto) ->
- #protocol_field_begin{type = Type} = read(Proto, field_begin),
+skip_struct_loop(Proto0) ->
+ {Proto1, #protocol_field_begin{type = Type}} = read(Proto0, field_begin),
case Type of
?tType_STOP ->
- ok;
+ {Proto1, ok};
_Else ->
- skip(Proto, Type),
- ok = read(Proto, field_end),
- skip_struct_loop(Proto)
+ {Proto2, ok} = skip(Proto1, Type),
+ {Proto3, ok} = read(Proto2, field_end),
+ skip_struct_loop(Proto3)
end.
-skip_map_loop(Proto, Map = #protocol_map_begin{ktype = Ktype,
- vtype = Vtype,
- size = Size}) ->
+skip_map_loop(Proto0, Map = #protocol_map_begin{ktype = Ktype,
+ vtype = Vtype,
+ size = Size}) ->
case Size of
N when N > 0 ->
- skip(Proto, Ktype),
- skip(Proto, Vtype),
- skip_map_loop(Proto,
+ {Proto1, ok} = skip(Proto0, Ktype),
+ {Proto2, ok} = skip(Proto1, Vtype),
+ skip_map_loop(Proto2,
Map#protocol_map_begin{size = Size - 1});
- 0 -> ok
+ 0 -> {Proto0, ok}
end.
-skip_set_loop(Proto, Map = #protocol_set_begin{etype = Etype,
- size = Size}) ->
+skip_set_loop(Proto0, Map = #protocol_set_begin{etype = Etype,
+ size = Size}) ->
case Size of
N when N > 0 ->
- skip(Proto, Etype),
- skip_set_loop(Proto,
+ {Proto1, ok} = skip(Proto0, Etype),
+ skip_set_loop(Proto1,
Map#protocol_set_begin{size = Size - 1});
- 0 -> ok
+ 0 -> {Proto0, ok}
end.
-skip_list_loop(Proto, Map = #protocol_list_begin{etype = Etype,
- size = Size}) ->
+skip_list_loop(Proto0, Map = #protocol_list_begin{etype = Etype,
+ size = Size}) ->
case Size of
N when N > 0 ->
- skip(Proto, Etype),
- skip_list_loop(Proto,
+ {Proto1, ok} = skip(Proto0, Etype),
+ skip_list_loop(Proto1,
Map#protocol_list_begin{size = Size - 1});
- 0 -> ok
+ 0 -> {Proto0, ok}
end.
@@ -271,86 +312,91 @@ skip_list_loop(Proto, Map = #protocol_li
%%
%% Description:
%%--------------------------------------------------------------------
-write(Proto, {{struct, StructDef}, Data})
+-spec write(#protocol{}, term()) -> {#protocol{}, ok | {error, _Reason}}.
+
+write(Proto0, {{struct, StructDef}, Data})
when is_list(StructDef), is_tuple(Data), length(StructDef) == size(Data) - 1 ->
[StructName | Elems] = tuple_to_list(Data),
- ok = write(Proto, #protocol_struct_begin{name = StructName}),
- ok = struct_write_loop(Proto, StructDef, Elems),
- ok = write(Proto, struct_end),
- ok;
+ {Proto1, ok} = write(Proto0, #protocol_struct_begin{name = StructName}),
+ {Proto2, ok} = struct_write_loop(Proto1, StructDef, Elems),
+ {Proto3, ok} = write(Proto2, struct_end),
+ {Proto3, ok};
write(Proto, {{struct, {Module, StructureName}}, Data})
when is_atom(Module),
is_atom(StructureName),
element(1, Data) =:= StructureName ->
- StructType = Module:struct_info(StructureName),
write(Proto, {Module:struct_info(StructureName), Data});
-write(Proto, {{list, Type}, Data})
+write(Proto0, {{list, Type}, Data})
when is_list(Data) ->
- ok = write(Proto,
+ {Proto1, ok} = write(Proto0,
#protocol_list_begin{
etype = term_to_typeid(Type),
size = length(Data)
}),
- lists:foreach(fun(Elem) ->
- ok = write(Proto, {Type, Elem})
- end,
- Data),
- ok = write(Proto, list_end),
- ok;
-
-write(Proto, {{map, KeyType, ValType}, Data}) ->
- ok = write(Proto,
- #protocol_map_begin{
- ktype = term_to_typeid(KeyType),
- vtype = term_to_typeid(ValType),
- size = dict:size(Data)
- }),
- dict:fold(fun(KeyData, ValData, _Acc) ->
- ok = write(Proto, {KeyType, KeyData}),
- ok = write(Proto, {ValType, ValData})
- end,
- _AccO = ok,
- Data),
- ok = write(Proto, map_end),
- ok;
+ Proto2 = lists:foldl(fun(Elem, ProtoIn) ->
+ {ProtoOut, ok} = write(ProtoIn, {Type, Elem}),
+ ProtoOut
+ end,
+ Proto1,
+ Data),
+ {Proto3, ok} = write(Proto2, list_end),
+ {Proto3, ok};
+
+write(Proto0, {{map, KeyType, ValType}, Data}) ->
+ {Proto1, ok} = write(Proto0,
+ #protocol_map_begin{
+ ktype = term_to_typeid(KeyType),
+ vtype = term_to_typeid(ValType),
+ size = dict:size(Data)
+ }),
+ Proto2 = dict:fold(fun(KeyData, ValData, ProtoS0) ->
+ {ProtoS1, ok} = write(ProtoS0, {KeyType, KeyData}),
+ {ProtoS2, ok} = write(ProtoS1, {ValType, ValData}),
+ ProtoS2
+ end,
+ Proto1,
+ Data),
+ {Proto3, ok} = write(Proto2, map_end),
+ {Proto3, ok};
-write(Proto, {{set, Type}, Data}) ->
+write(Proto0, {{set, Type}, Data}) ->
true = sets:is_set(Data),
- ok = write(Proto,
- #protocol_set_begin{
- etype = term_to_typeid(Type),
- size = sets:size(Data)
- }),
- sets:fold(fun(Elem, _Acc) ->
- ok = write(Proto, {Type, Elem})
- end,
- _Acc0 = ok,
- Data),
- ok = write(Proto, set_end),
- ok;
-
-write(#protocol{module = Module,
- data = ModuleData}, Data) ->
- Module:write(ModuleData, Data).
-
-struct_write_loop(Proto, [{Fid, Type} | RestStructDef], [Data | RestData]) ->
- case Data of
- undefined ->
- % null fields are skipped in response
- skip;
- _ ->
- ok = write(Proto,
- #protocol_field_begin{
- type = term_to_typeid(Type),
- id = Fid
- }),
- ok = write(Proto, {Type, Data}),
- ok = write(Proto, field_end)
- end,
- struct_write_loop(Proto, RestStructDef, RestData);
+ {Proto1, ok} = write(Proto0,
+ #protocol_set_begin{
+ etype = term_to_typeid(Type),
+ size = sets:size(Data)
+ }),
+ Proto2 = sets:fold(fun(Elem, ProtoIn) ->
+ {ProtoOut, ok} = write(ProtoIn, {Type, Elem}),
+ ProtoOut
+ end,
+ Proto1,
+ Data),
+ {Proto3, ok} = write(Proto2, set_end),
+ {Proto3, ok};
+
+write(Proto = #protocol{module = Module,
+ data = ModuleData}, Data) ->
+ {NewData, Result} = Module:write(ModuleData, Data),
+ {Proto#protocol{data = NewData}, Result}.
+
+struct_write_loop(Proto0, [{Fid, Type} | RestStructDef], [Data | RestData]) ->
+ NewProto = case Data of
+ undefined ->
+ Proto0; % null fields are skipped in response
+ _ ->
+ {Proto1, ok} = write(Proto0,
+ #protocol_field_begin{
+ type = term_to_typeid(Type),
+ id = Fid
+ }),
+ {Proto2, ok} = write(Proto1, {Type, Data}),
+ {Proto3, ok} = write(Proto2, field_end),
+ Proto3
+ end,
+ struct_write_loop(NewProto, RestStructDef, RestData);
struct_write_loop(Proto, [], []) ->
- ok = write(Proto, field_stop),
- ok.
+ write(Proto, field_stop).
Modified: incubator/thrift/trunk/lib/erl/src/thrift_server.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_server.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_server.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_server.erl Thu Aug 19 05:06:02 2010
@@ -126,7 +126,7 @@ handle_info({inet_async, ListenSocket, R
{stop, Reason, State}
end;
-handle_info({inet_async, ListenSocket, Ref, Error}, State) ->
+handle_info({inet_async, _ListenSocket, _Ref, Error}, State) ->
error_logger:error_msg("Error in acceptor: ~p~n", [Error]),
{stop, Error, State};
@@ -177,7 +177,7 @@ start_processor(Socket, Service, Handler
{ok, SocketTransport} = thrift_socket_transport:new(Socket),
{ok, BufferedTransport} = thrift_buffered_transport:new(SocketTransport),
{ok, Protocol} = thrift_binary_protocol:new(BufferedTransport),
- {ok, Protocol, Protocol}
+ {ok, Protocol}
end,
spawn(thrift_processor, init, [{Server, ProtoGen, Service, Handler}]).
Modified: incubator/thrift/trunk/lib/erl/src/thrift_socket_server.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_socket_server.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_socket_server.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_socket_server.erl Thu Aug 19 05:06:02 2010
@@ -166,13 +166,12 @@ gen_tcp_listen(Port, Opts, State) ->
new_acceptor(State=#thrift_socket_server{max=0}) ->
error_logger:error_msg("Not accepting new connections"),
State#thrift_socket_server{acceptor=null};
-new_acceptor(State=#thrift_socket_server{acceptor=OldPid, listen=Listen,
+new_acceptor(State=#thrift_socket_server{listen=Listen,
service=Service, handler=Handler,
socket_opts=Opts, framed=Framed
}) ->
Pid = proc_lib:spawn_link(?MODULE, acceptor_loop,
[{self(), Listen, Service, Handler, Opts, Framed}]),
-%% error_logger:info_msg("Spawning new acceptor: ~p => ~p", [OldPid, Pid]),
State#thrift_socket_server{acceptor=Pid}.
acceptor_loop({Server, Listen, Service, Handler, SocketOpts, Framed})
@@ -188,7 +187,7 @@ acceptor_loop({Server, Listen, Service,
false -> thrift_buffered_transport:new(SocketTransport)
end,
{ok, Protocol} = thrift_binary_protocol:new(Transport),
- {ok, IProt=Protocol, OProt=Protocol}
+ {ok, Protocol}
end,
thrift_processor:init({Server, ProtoGen, Service, Handler});
{error, closed} ->
Modified: incubator/thrift/trunk/lib/erl/src/thrift_socket_transport.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_socket_transport.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_socket_transport.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_socket_transport.erl Thu Aug 19 05:06:02 2010
@@ -29,6 +29,8 @@
-record(data, {socket,
recv_timeout=infinity}).
+-type state() :: #data{}.
+-include("thrift_transport_behaviour.hrl").
new(Socket) ->
new(Socket, []).
@@ -45,25 +47,26 @@ new(Socket, Opts) when is_list(Opts) ->
thrift_transport:new(?MODULE, State).
%% Data :: iolist()
-write(#data{socket = Socket}, Data) ->
- gen_tcp:send(Socket, Data).
+write(This = #data{socket = Socket}, Data) ->
+ {This, gen_tcp:send(Socket, Data)}.
-read(#data{socket=Socket, recv_timeout=Timeout}, Len)
+read(This = #data{socket=Socket, recv_timeout=Timeout}, Len)
when is_integer(Len), Len >= 0 ->
case gen_tcp:recv(Socket, Len, Timeout) of
Err = {error, timeout} ->
error_logger:info_msg("read timeout: peer conn ~p", [inet:peername(Socket)]),
gen_tcp:close(Socket),
- Err;
- Data -> Data
+ {This, Err};
+ Data ->
+ {This, Data}
end.
%% We can't really flush - everything is flushed when we write
-flush(_) ->
- ok.
+flush(This) ->
+ {This, ok}.
-close(#data{socket = Socket}) ->
- gen_tcp:close(Socket).
+close(This = #data{socket = Socket}) ->
+ {This, gen_tcp:close(Socket)}.
%%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Modified: incubator/thrift/trunk/lib/erl/src/thrift_transport.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_transport.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_transport.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_transport.erl Thu Aug 19 05:06:02 2010
@@ -37,21 +37,42 @@ behaviour_info(callbacks) ->
-record(transport, {module, data}).
+-ifdef(transport_wrapper_module).
+-define(debug_wrap(Transport),
+ case Transport#transport.module of
+ ?transport_wrapper_module ->
+ Transport;
+ _Else ->
+ {ok, Result} = ?transport_wrapper_module:new(Transport),
+ Result
+ end).
+-else.
+-define(debug_wrap(Transport), Transport).
+-endif.
+
new(Module, Data) when is_atom(Module) ->
- {ok, #transport{module = Module,
- data = Data}}.
+ Transport0 = #transport{module = Module, data = Data},
+ Transport1 = ?debug_wrap(Transport0),
+ {ok, Transport1}.
-%% Data :: iolist()
+-spec write(#transport{}, iolist() | binary()) -> {#transport{}, ok | {error, _Reason}}.
write(Transport, Data) ->
Module = Transport#transport.module,
- Module:write(Transport#transport.data, Data).
+ {NewTransData, Result} = Module:write(Transport#transport.data, Data),
+ {Transport#transport{data = NewTransData}, Result}.
+-spec read(#transport{}, non_neg_integer()) -> {#transport{}, {ok, binary()} | {error, _Reason}}.
read(Transport, Len) when is_integer(Len) ->
Module = Transport#transport.module,
- Module:read(Transport#transport.data, Len).
-
-flush(#transport{module = Module, data = Data}) ->
- Module:flush(Data).
+ {NewTransData, Result} = Module:read(Transport#transport.data, Len),
+ {Transport#transport{data = NewTransData}, Result}.
-close(#transport{module = Module, data = Data}) ->
- Module:close(Data).
+-spec flush(#transport{}) -> {#transport{}, ok | {error, _Reason}}.
+flush(Transport = #transport{module = Module, data = Data}) ->
+ {NewTransData, Result} = Module:flush(Data),
+ {Transport#transport{data = NewTransData}, Result}.
+
+-spec close(#transport{}) -> {#transport{}, ok | {error, _Reason}}.
+close(Transport = #transport{module = Module, data = Data}) ->
+ {NewTransData, Result} = Module:close(Data),
+ {Transport#transport{data = NewTransData}, Result}.
Added: incubator/thrift/trunk/lib/erl/src/thrift_transport_state_test.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_transport_state_test.erl?rev=987018&view=auto
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_transport_state_test.erl (added)
+++ incubator/thrift/trunk/lib/erl/src/thrift_transport_state_test.erl Thu Aug 19 05:06:02 2010
@@ -0,0 +1,117 @@
+%%
+%% Licensed to the Apache Software Foundation (ASF) under one
+%% or more contributor license agreements. See the NOTICE file
+%% distributed with this work for additional information
+%% regarding copyright ownership. The ASF licenses this file
+%% to you under the Apache License, Version 2.0 (the
+%% "License"); you may not use this file except in compliance
+%% with the License. You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+
+-module(thrift_transport_state_test).
+
+-behaviour(gen_server).
+-behaviour(thrift_transport).
+
+%% API
+-export([new/1]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+%% thrift_transport callbacks
+-export([write/2, read/2, flush/1, close/1]).
+
+-record(trans, {wrapped, % #thrift_transport{}
+ version :: integer(),
+ counter :: pid()
+ }).
+-type state() :: #trans{}.
+-include("thrift_transport_behaviour.hrl").
+
+-record(state, {cversion :: integer()}).
+
+
+new(WrappedTransport) ->
+ case gen_server:start_link(?MODULE, [], []) of
+ {ok, Pid} ->
+ Trans = #trans{wrapped = WrappedTransport,
+ version = 0,
+ counter = Pid},
+ thrift_transport:new(?MODULE, Trans);
+ Else ->
+ Else
+ end.
+
+%%====================================================================
+%% thrift_transport callbacks
+%%====================================================================
+
+write(Transport0 = #trans{wrapped = Wrapped0}, Data) ->
+ Transport1 = check_version(Transport0),
+ {Wrapped1, Result} = thrift_transport:write(Wrapped0, Data),
+ Transport2 = Transport1#trans{wrapped = Wrapped1},
+ {Transport2, Result}.
+
+flush(Transport0 = #trans{wrapped = Wrapped0}) ->
+ Transport1 = check_version(Transport0),
+ {Wrapped1, Result} = thrift_transport:flush(Wrapped0),
+ Transport2 = Transport1#trans{wrapped = Wrapped1},
+ {Transport2, Result}.
+
+close(Transport0 = #trans{wrapped = Wrapped0}) ->
+ Transport1 = check_version(Transport0),
+ shutdown_counter(Transport1),
+ {Wrapped1, Result} = thrift_transport:close(Wrapped0),
+ Transport2 = Transport1#trans{wrapped = Wrapped1},
+ {Transport2, Result}.
+
+read(Transport0 = #trans{wrapped = Wrapped0}, Len) ->
+ Transport1 = check_version(Transport0),
+ {Wrapped1, Result} = thrift_transport:read(Wrapped0, Len),
+ Transport2 = Transport1#trans{wrapped = Wrapped1},
+ {Transport2, Result}.
+
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+init([]) ->
+ {ok, #state{cversion = 0}}.
+
+handle_call(check_version, _From, State = #state{cversion = Version}) ->
+ {reply, Version, State#state{cversion = Version+1}}.
+
+handle_cast(shutdown, State) ->
+ {stop, normal, State}.
+
+handle_info(_Info, State) -> {noreply, State}.
+code_change(_OldVsn, State, _Extra) -> {ok, State}.
+terminate(_Reason, _State) -> ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+
+check_version(Transport = #trans{version = Version, counter = Counter}) ->
+ case gen_server:call(Counter, check_version) of
+ Version ->
+ Transport#trans{version = Version+1};
+ _Else ->
+ % State wasn't propagated properly. Die.
+ erlang:error(state_not_propagated)
+ end.
+
+shutdown_counter(#trans{counter = Counter}) ->
+ gen_server:cast(Counter, shutdown).
Modified: incubator/thrift/trunk/test/erl/Makefile
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/erl/Makefile?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/test/erl/Makefile (original)
+++ incubator/thrift/trunk/test/erl/Makefile Thu Aug 19 05:06:02 2010
@@ -29,7 +29,7 @@ SRCDIR=src
ALL_INCLUDEDIR=$(GEN_INCLUDEDIR) $(INCLUDEDIR) ../../lib/erl/include
INCLUDEFLAGS=$(patsubst %,-I%, ${ALL_INCLUDEDIR})
-MODULES = stress_server test_server test_disklog test_membuffer test_tether
+MODULES = stress_server test_server test_client test_disklog test_membuffer
INCLUDES =
TARGETS = $(patsubst %,${TARGETDIR}/%.beam,${MODULES})
@@ -55,11 +55,11 @@ ${GENDIR}/: ${RPCFILE}
${GEN_TARGETDIR}/: ${GENDIR}/
rm -rf ${GEN_TARGETDIR}
mkdir -p ${GEN_TARGETDIR}
- erlc ${INCLUDEFLAGS} -o ${GEN_TARGETDIR} ${GEN_SRCDIR}/*.erl
+ erlc ${ERLC_FLAGS} ${INCLUDEFLAGS} -o ${GEN_TARGETDIR} ${GEN_SRCDIR}/*.erl
$(TARGETS): ${TARGETDIR}/%.beam: ${SRCDIR}/%.erl ${GEN_INCLUDEDIR}/ ${HEADERS}
mkdir -p ${TARGETDIR}
- erlc ${INCLUDEFLAGS} -o ${TARGETDIR} $<
+ erlc ${ERLC_FLAGS} ${INCLUDEFLAGS} -o ${TARGETDIR} $<
clean:
rm -f ${TARGETDIR}/*.beam
Added: incubator/thrift/trunk/test/erl/src/test_client.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/erl/src/test_client.erl?rev=987018&view=auto
==============================================================================
--- incubator/thrift/trunk/test/erl/src/test_client.erl (added)
+++ incubator/thrift/trunk/test/erl/src/test_client.erl Thu Aug 19 05:06:02 2010
@@ -0,0 +1,132 @@
+%%
+%% Licensed to the Apache Software Foundation (ASF) under one
+%% or more contributor license agreements. See the NOTICE file
+%% distributed with this work for additional information
+%% regarding copyright ownership. The ASF licenses this file
+%% to you under the Apache License, Version 2.0 (the
+%% "License"); you may not use this file except in compliance
+%% with the License. You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+
+-module(test_client).
+
+-export([start/0, start/1]).
+
+-include("thriftTest_types.hrl").
+
+-record(options, {port = 9090,
+ client_opts = []}).
+
+parse_args(Args) -> parse_args(Args, #options{}).
+parse_args([], Opts) -> Opts;
+parse_args([Head | Rest], Opts) ->
+ NewOpts =
+ case catch list_to_integer(Head) of
+ Port when is_integer(Port) ->
+ Opts#options{port = Port};
+ _Else ->
+ case Head of
+ "framed" ->
+ Opts#options{client_opts = [{framed, true} | Opts#options.client_opts]};
+ "" ->
+ Opts;
+ _Else ->
+ erlang:error({bad_arg, Head})
+ end
+ end,
+ parse_args(Rest, NewOpts).
+
+
+start() -> start([]).
+start(Args) ->
+ #options{port = Port, client_opts = ClientOpts} = parse_args(Args),
+ {ok, Client0} = thrift_client_util:new(
+ "127.0.0.1", Port, thriftTest_thrift, ClientOpts),
+
+ DemoXtruct = #xtruct{
+ string_thing = <<"Zero">>,
+ byte_thing = 1,
+ i32_thing = 9128361,
+ i64_thing = 9223372036854775807},
+
+ DemoNest = #xtruct2{
+ byte_thing = 7,
+ struct_thing = DemoXtruct,
+ % Note that we don't set i32_thing, it will come back as undefined
+ % from the Python server, but 0 from the C++ server, since it is not
+ % optional
+ i32_thing = 2},
+
+ % Is it safe to match these things?
+ DemoDict = dict:from_list([ {Key, Key-10} || Key <- lists:seq(0,10) ]),
+ DemoSet = sets:from_list([ Key || Key <- lists:seq(-3,3) ]),
+
+ %DemoInsane = #insanity{
+ % userMap = dict:from_list([{?thriftTest_FIVE, 5000}]),
+ % xtructs = [#xtruct{ string_thing = <<"Truck">>, byte_thing = 8, i32_thing = 8, i64_thing = 8}]},
+
+ {Client01, {ok, ok}} = thrift_client:call(Client0, testVoid, []),
+
+ {Client02, {ok, <<"Test">>}} = thrift_client:call(Client01, testString, ["Test"]),
+ {Client03, {ok, <<"Test">>}} = thrift_client:call(Client02, testString, [<<"Test">>]),
+ {Client04, {ok, 63}} = thrift_client:call(Client03, testByte, [63]),
+ {Client05, {ok, -1}} = thrift_client:call(Client04, testI32, [-1]),
+ {Client06, {ok, 0}} = thrift_client:call(Client05, testI32, [0]),
+ {Client07, {ok, -34359738368}} = thrift_client:call(Client06, testI64, [-34359738368]),
+ {Client08, {ok, -5.2098523}} = thrift_client:call(Client07, testDouble, [-5.2098523]),
+ {Client09, {ok, DemoXtruct}} = thrift_client:call(Client08, testStruct, [DemoXtruct]),
+ {Client10, {ok, DemoNest}} = thrift_client:call(Client09, testNest, [DemoNest]),
+ {Client11, {ok, DemoDict}} = thrift_client:call(Client10, testMap, [DemoDict]),
+ {Client12, {ok, DemoSet}} = thrift_client:call(Client11, testSet, [DemoSet]),
+ {Client13, {ok, [-1,2,3]}} = thrift_client:call(Client12, testList, [[-1,2,3]]),
+ {Client14, {ok, 1}} = thrift_client:call(Client13, testEnum, [?thriftTest_ONE]),
+ {Client15, {ok, 309858235082523}} = thrift_client:call(Client14, testTypedef, [309858235082523]),
+
+ % No python implementation, but works with C++ and Erlang.
+ %{Client16, {ok, InsaneResult}} = thrift_client:call(Client15, testInsanity, [DemoInsane]),
+ %io:format("~p~n", [InsaneResult]),
+ Client16 = Client15,
+
+ {Client17, {ok, #xtruct{string_thing = <<"Message">>}}} =
+ thrift_client:call(Client16, testMultiException, ["Safe", "Message"]),
+
+ Client18 =
+ try
+ {ClientS1, Result1} = thrift_client:call(Client17, testMultiException, ["Xception", "Message"]),
+ io:format("Unexpected return! ~p~n", [Result1]),
+ ClientS1
+ catch
+ throw:{ClientS2, {exception, ExnS1 = #xception{}}} ->
+ #xception{errorCode = 1001, message = <<"This is an Xception">>} = ExnS1,
+ ClientS2;
+ throw:{ClientS2, {exception, _ExnS1 = #xception2{}}} ->
+ io:format("Wrong exception type!~n", []),
+ ClientS2
+ end,
+
+ Client19 =
+ try
+ {ClientS3, Result2} = thrift_client:call(Client18, testMultiException, ["Xception2", "Message"]),
+ io:format("Unexpected return! ~p~n", [Result2]),
+ ClientS3
+ catch
+ throw:{ClientS4, {exception, _ExnS2 = #xception{}}} ->
+ io:format("Wrong exception type!~n", []),
+ ClientS4;
+ throw:{ClientS4, {exception, ExnS2 = #xception2{}}} ->
+ #xception2{errorCode = 2002,
+ struct_thing = #xtruct{
+ string_thing = <<"This is an Xception2">>}} = ExnS2,
+ ClientS4
+ end,
+
+ thrift_client:close(Client19).
Modified: incubator/thrift/trunk/test/erl/src/test_disklog.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/erl/src/test_disklog.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/test/erl/src/test_disklog.erl (original)
+++ incubator/thrift/trunk/test/erl/src/test_disklog.erl Thu Aug 19 05:06:02 2010
@@ -29,20 +29,21 @@ t() ->
{size, {1024*1024, 10}}]),
{ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
TransportFactory, []),
- {ok, Client} = thrift_client:start_link(ProtocolFactory, thriftTest_thrift),
+ {ok, Proto} = ProtocolFactory(),
+ {ok, Client0} = thrift_client:new(Proto, thriftTest_thrift),
io:format("Client started~n"),
% We have to make oneway calls into this client only since otherwise it will try
% to read from the disklog and go boom.
- {ok, ok} = thrift_client:call(Client, testOneway, [16#deadbeef]),
+ {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]),
io:format("Call written~n"),
% Use the send_call method to write a non-oneway call into the log
- ok = thrift_client:send_call(Client, testString, [<<"hello world">>]),
+ {Client2, ok} = thrift_client:send_call(Client1, testString, [<<"hello world">>]),
io:format("Non-oneway call sent~n"),
- ok = thrift_client:close(Client),
+ {_Client3, ok} = thrift_client:close(Client2),
io:format("Client closed~n"),
ok.
@@ -61,21 +62,22 @@ t_base64() ->
thrift_buffered_transport:new_transport_factory(B64Factory),
{ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
BufFactory, []),
- {ok, Client} = thrift_client:start_link(ProtocolFactory, thriftTest_thrift),
+ {ok, Proto} = ProtocolFactory(),
+ {ok, Client0} = thrift_client:new(Proto, thriftTest_thrift),
io:format("Client started~n"),
% We have to make oneway calls into this client only since otherwise it will try
% to read from the disklog and go boom.
- {ok, ok} = thrift_client:call(Client, testOneway, [16#deadbeef]),
+ {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]),
io:format("Call written~n"),
% Use the send_call method to write a non-oneway call into the log
- ok = thrift_client:send_call(Client, testString, [<<"hello world">>]),
+ {Client2, ok} = thrift_client:send_call(Client1, testString, [<<"hello world">>]),
io:format("Non-oneway call sent~n"),
- ok = thrift_client:close(Client),
+ {_Client3, ok} = thrift_client:close(Client2),
io:format("Client closed~n"),
ok.
-
+
Modified: incubator/thrift/trunk/test/erl/src/test_membuffer.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/erl/src/test_membuffer.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/test/erl/src/test_membuffer.erl (original)
+++ incubator/thrift/trunk/test/erl/src/test_membuffer.erl Thu Aug 19 05:06:02 2010
@@ -30,12 +30,12 @@ test_data() ->
t1() ->
{ok, Transport} = thrift_memory_buffer:new(),
- {ok, Protocol} = thrift_binary_protocol:new(Transport),
+ {ok, Protocol0} = thrift_binary_protocol:new(Transport),
TestData = test_data(),
- ok = thrift_protocol:write(Protocol,
+ {Protocol1, ok} = thrift_protocol:write(Protocol0,
{{struct, element(2, thriftTest_types:struct_info('xtruct'))},
TestData}),
- {ok, Result} = thrift_protocol:read(Protocol,
+ {_Protocol2, {ok, Result}} = thrift_protocol:read(Protocol1,
{struct, element(2, thriftTest_types:struct_info('xtruct'))},
'xtruct'),
@@ -44,12 +44,12 @@ t1() ->
t2() ->
{ok, Transport} = thrift_memory_buffer:new(),
- {ok, Protocol} = thrift_binary_protocol:new(Transport),
+ {ok, Protocol0} = thrift_binary_protocol:new(Transport),
TestData = test_data(),
- ok = thrift_protocol:write(Protocol,
+ {Protocol1, ok} = thrift_protocol:write(Protocol0,
{{struct, element(2, thriftTest_types:struct_info('xtruct'))},
TestData}),
- {ok, Result} = thrift_protocol:read(Protocol,
+ {_Protocol2, {ok, Result}} = thrift_protocol:read(Protocol1,
{struct, element(2, thriftTest_types:struct_info('xtruct3'))},
'xtruct3'),
@@ -61,12 +61,12 @@ t2() ->
t3() ->
{ok, Transport} = thrift_memory_buffer:new(),
- {ok, Protocol} = thrift_binary_protocol:new(Transport),
+ {ok, Protocol0} = thrift_binary_protocol:new(Transport),
TestData = #bools{im_true = true, im_false = false},
- ok = thrift_protocol:write(Protocol,
+ {Protocol1, ok} = thrift_protocol:write(Protocol0,
{{struct, element(2, thriftTest_types:struct_info('bools'))},
TestData}),
- {ok, Result} = thrift_protocol:read(Protocol,
+ {_Protocol2, {ok, Result}} = thrift_protocol:read(Protocol1,
{struct, element(2, thriftTest_types:struct_info('bools'))},
'bools'),
@@ -74,8 +74,23 @@ t3() ->
true = TestData#bools.im_false =:= Result#bools.im_false.
+t4() ->
+ {ok, Transport} = thrift_memory_buffer:new(),
+ {ok, Protocol0} = thrift_binary_protocol:new(Transport),
+ TestData = #insanity{xtructs=[]},
+ {Protocol1, ok} = thrift_protocol:write(Protocol0,
+ {{struct, element(2, thriftTest_types:struct_info('insanity'))},
+ TestData}),
+ {_Protocol2, {ok, Result}} = thrift_protocol:read(Protocol1,
+ {struct, element(2, thriftTest_types:struct_info('insanity'))},
+ 'insanity'),
+
+ TestData = Result.
+
+
t() ->
t1(),
t2(),
- t3().
+ t3(),
+ t4().
Modified: incubator/thrift/trunk/test/erl/src/test_server.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/erl/src/test_server.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/test/erl/src/test_server.erl (original)
+++ incubator/thrift/trunk/test/erl/src/test_server.erl Thu Aug 19 05:06:02 2010
@@ -19,12 +19,42 @@
-module(test_server).
--export([start_link/1, handle_function/2]).
+-export([go/0, go/1, start_link/2, handle_function/2]).
-include("thriftTest_types.hrl").
-start_link(Port) ->
- thrift_server:start_link(Port, thriftTest_thrift, ?MODULE).
+-record(options, {port = 9090,
+ server_opts = []}).
+
+parse_args(Args) -> parse_args(Args, #options{}).
+parse_args([], Opts) -> Opts;
+parse_args([Head | Rest], Opts) ->
+ NewOpts =
+ case catch list_to_integer(Head) of
+ Port when is_integer(Port) ->
+ Opts#options{port = Port};
+ _Else ->
+ case Head of
+ "framed" ->
+ Opts#options{server_opts = [{framed, true} | Opts#options.server_opts]};
+ "" ->
+ Opts;
+ _Else ->
+ erlang:error({bad_arg, Head})
+ end
+ end,
+ parse_args(Rest, NewOpts).
+
+go() -> go([]).
+go(Args) ->
+ #options{port = Port, server_opts = ServerOpts} = parse_args(Args),
+ spawn(fun() -> start_link(Port, ServerOpts), receive after infinity -> ok end end).
+
+start_link(Port, ServerOpts) ->
+ thrift_socket_server:start([{handler, ?MODULE},
+ {service, thriftTest_thrift},
+ {port, Port}] ++
+ ServerOpts).
handle_function(testVoid, {}) ->
@@ -124,12 +154,12 @@ handle_function(testInsanity, {Insanity}
{?thriftTest_THREE, Crazy}]),
SecondMap = dict:from_list([{?thriftTest_SIX, Looney}]),
-
+
Insane = dict:from_list([{1, FirstMap},
{2, SecondMap}]),
-
+
io:format("Return = ~p~n", [Insane]),
-
+
{reply, Insane};
handle_function(testMulti, Args = {Arg0, Arg1, Arg2, _Arg3, Arg4, Arg5})
@@ -150,7 +180,7 @@ handle_function(testException, {String})
case String of
<<"Xception">> ->
throw(#xception{errorCode = 1001,
- message = <<"This is an Xception">>});
+ message = String});
_ ->
ok
end;
Modified: incubator/thrift/trunk/tutorial/erl/client.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/tutorial/erl/client.erl?rev=987018&r1=987017&r2=987018&view=diff
==============================================================================
--- incubator/thrift/trunk/tutorial/erl/client.erl (original)
+++ incubator/thrift/trunk/tutorial/erl/client.erl Thu Aug 19 05:06:02 2010
@@ -29,46 +29,50 @@ p(X) ->
t() ->
Port = 9999,
-
- {ok, Client} = thrift_client:start_link("127.0.0.1",
- Port,
- calculator_thrift),
- thrift_client:call(Client, ping, []),
+ {ok, Client0} = thrift_client_util:new("127.0.0.1",
+ Port,
+ calculator_thrift,
+ []),
+
+ {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []),
io:format("ping~n", []),
- {ok, Sum} = thrift_client:call(Client, add, [1, 1]),
+ {Client2, {ok, Sum}} = thrift_client:call(Client1, add, [1, 1]),
io:format("1+1=~p~n", [Sum]),
- {ok, Sum1} = thrift_client:call(Client, add, [1, 4]),
+ {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]),
io:format("1+4=~p~n", [Sum1]),
Work = #work{op=?tutorial_SUBTRACT,
num1=15,
num2=10},
- {ok, Diff} = thrift_client:call(Client, calculate, [1, Work]),
+ {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]),
io:format("15-10=~p~n", [Diff]),
- {ok, Log} = thrift_client:call(Client, getStruct, [1]),
+ {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]),
io:format("Log: ~p~n", [Log]),
- try
- Work1 = #work{op=?tutorial_DIVIDE,
- num1=1,
- num2=0},
- {ok, _Quot} = thrift_client:call(Client, calculate, [2, Work1]),
-
- io:format("LAME: exception handling is broken~n", [])
- catch
- Z ->
- io:format("Got exception where expecting - the " ++
- "following is NOT a problem!!!~n"),
- p(Z)
- end,
+ Client6 =
+ try
+ Work1 = #work{op=?tutorial_DIVIDE,
+ num1=1,
+ num2=0},
+ {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, [2, Work1]),
+
+ io:format("LAME: exception handling is broken~n", []),
+ ClientS1
+ catch
+ throw:{ClientS2, Z} ->
+ io:format("Got exception where expecting - the " ++
+ "following is NOT a problem!!!~n"),
+ p(Z),
+ ClientS2
+ end,
- {ok, ok} = thrift_client:call(Client, zip, []),
+ {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []),
io:format("zip~n", []),
- ok = thrift_client:close(Client),
+ {_Client8, ok} = thrift_client:close(Client7),
ok.