You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by dr...@apache.org on 2010/08/31 00:05:30 UTC

svn commit: r990979 - in /incubator/thrift/trunk: lib/erl/README lib/erl/src/thrift_client.erl lib/erl/src/thrift_client_util.erl test/erl/Makefile test/erl/src/test_tether.erl tutorial/erl/client.erl

Author: dreiss
Date: Mon Aug 30 22:05:29 2010
New Revision: 990979

URL: http://svn.apache.org/viewvc?rev=990979&view=rev
Log:
erlang: Client refactor, part 1

- Client is no longer a separate process.
- Simplified constructors moved into another module.
- All functions and exceptions return the new client,
  to allow for future statefulness in the client.

NOTE: With the new library and old gen-code, attempting to call a
nonexistent function will result in an exit.

TODO: fix docs and tests (tether test is not meaningful)

Added:
    incubator/thrift/trunk/lib/erl/src/thrift_client_util.erl
Removed:
    incubator/thrift/trunk/test/erl/src/test_tether.erl
Modified:
    incubator/thrift/trunk/lib/erl/README
    incubator/thrift/trunk/lib/erl/src/thrift_client.erl
    incubator/thrift/trunk/test/erl/Makefile
    incubator/thrift/trunk/tutorial/erl/client.erl

Modified: incubator/thrift/trunk/lib/erl/README
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/README?rev=990979&r1=990978&r2=990979&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/README (original)
+++ incubator/thrift/trunk/lib/erl/README Mon Aug 30 22:05:29 2010
@@ -25,32 +25,19 @@ Example
 
 Example session using thrift_client:
 
-118> f(), {ok, C} = thrift_client:start_link("localhost", 9090, thriftTest_thrif
-t).
-{ok,<0.271.0>}
-119> thrift_client:call(C, testVoid, []).
+1> {ok, C0} = thrift_client_util:new("localhost", 9090, thriftTest_thrift, []), ok.
+ok
+2> {C1, R1} = thrift_client:call(C0, testVoid, []), R1.
 {ok,ok}
-120> thrift_client:call(C, testVoid, [asdf]).
+3> {C2, R2} = thrift_client:call(C1, testVoid, [asdf]), R2.
 {error,{bad_args,testVoid,[asdf]}}
-121> thrift_client:call(C, testI32, [123]).
+4> {C3, R3} = thrift_client:call(C2, testI32, [123]), R3.
 {ok,123}
-122> thrift_client:call(C, testOneway, [1]).
+5> {C4, R4} = thrift_client:call(C3, testOneway, [1]), R4.
 {ok,ok}
-123> catch thrift_client:call(C, testXception, ["foo"]).
+6> {C5, R5} = thrift_client:call(C4, testXception, ["foo"]), R5.
 {error,{no_function,testXception}}
-124> catch thrift_client:call(C, testException, ["foo"]).
+7> {C6, R6} = thrift_client:call(C5, testException, ["foo"]), R6.
 {ok,ok}
-125> catch thrift_client:call(C, testException, ["Xception"]).
-{xception,1001,"This is an Xception"}
-126> thrift_client:call(C, testException, ["Xception"]).
-
-=ERROR REPORT==== 24-Feb-2008::23:00:23 ===
-Error in process <0.269.0> with exit value: {{nocatch,{xception,1001,"This is an
- Xception"}},[{thrift_client,call,3},{erl_eval,do_apply,5},{shell,exprs,6},{shel
-l,eval_loop,3}]}
-
-** exited: {{nocatch,{xception,1001,"This is an Xception"}},
-            [{thrift_client,call,3},
-             {erl_eval,do_apply,5},
-             {shell,exprs,6},
-             {shell,eval_loop,3}]} **
+8> {C7, R7} = (catch thrift_client:call(C6, testException, ["Xception"])), R7.
+{exception,{xception,1001,<<"Xception">>}}

Modified: incubator/thrift/trunk/lib/erl/src/thrift_client.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_client.erl?rev=990979&r1=990978&r2=990979&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_client.erl (original)
+++ incubator/thrift/trunk/lib/erl/src/thrift_client.erl Mon Aug 30 22:05:29 2010
@@ -19,370 +19,123 @@
 
 -module(thrift_client).
 
--behaviour(gen_server).
-
 %% API
--export([start_link/2, start_link/3, start_link/4,
-         start/3, start/4,
-         call/3, cast/3, send_call/3, close/1]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
-         terminate/2, code_change/3]).
-
+-export([new/2, call/3, send_call/3, close/1]).
 
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--record(state, {service, protocol, seqid}).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server as a linked process.
-%%--------------------------------------------------------------------
-start_link(Host, Port, Service) when is_integer(Port), is_atom(Service) ->
-    start_link(Host, Port, Service, []).
-
-start_link(Host, Port, Service, Options) ->
-    start(Host, Port, Service, [{monitor, link} | Options]).
-
-start_link(ProtocolFactory, Service) ->
-    start(ProtocolFactory, Service, [{monitor, link}]).
-
-%%
-%% Splits client options into protocol options and transport options
-%%
-%% split_options([Options...]) -> {ProtocolOptions, TransportOptions}
-%%
-split_options(Options) ->
-    split_options(Options, [], [], []).
-
-split_options([], ClientIn, ProtoIn, TransIn) ->
-    {ClientIn, ProtoIn, TransIn};
-
-split_options([Opt = {OptKey, _} | Rest], ClientIn, ProtoIn, TransIn)
-  when OptKey =:= monitor ->
-    split_options(Rest, [Opt | ClientIn], ProtoIn, TransIn);
-
-split_options([Opt = {OptKey, _} | Rest], ClientIn, ProtoIn, TransIn)
-  when OptKey =:= strict_read;
-       OptKey =:= strict_write ->
-    split_options(Rest, ClientIn, [Opt | ProtoIn], TransIn);
-
-split_options([Opt = {OptKey, _} | Rest], ClientIn, ProtoIn, TransIn)
-  when OptKey =:= framed;
-       OptKey =:= connect_timeout;
-       OptKey =:= sockopts ->
-    split_options(Rest, ClientIn, ProtoIn, [Opt | TransIn]).
-
+-record(tclient, {service, protocol, seqid}).
 
-%%--------------------------------------------------------------------
-%% Function: start() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the server as an unlinked process.
-%%--------------------------------------------------------------------
 
-%% Backwards-compatible starter for the common-case of socket transports
-start(Host, Port, Service, Options)
-  when is_integer(Port), is_atom(Service), is_list(Options) ->
-    {ClientOpts, ProtoOpts, TransOpts} = split_options(Options),
-
-    {ok, TransportFactory} =
-        thrift_socket_transport:new_transport_factory(Host, Port, TransOpts),
-
-    {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
-                              TransportFactory, ProtoOpts),
-
-    start(ProtocolFactory, Service, ClientOpts).
-
-
-%% ProtocolFactory :: fun() -> thrift_protocol()
-start(ProtocolFactory, Service, ClientOpts)
-  when is_function(ProtocolFactory), is_atom(Service) ->
-    {Starter, Opts} =
-        case lists:keysearch(monitor, 1, ClientOpts) of
-            {value, {monitor, link}} ->
-                {start_link, []};
-            {value, {monitor, tether}} ->
-                {start, [{tether, self()}]};
-            _ ->
-                {start, []}
-        end,
-
-    Connect =
-        case lists:keysearch(connect, 1, ClientOpts) of
-            {value, {connect, Choice}} ->
-                Choice;
-            _ ->
-                %% By default, connect at creation-time.
-                true
-        end,
-
-
-    Started = gen_server:Starter(?MODULE, [Service, Opts], []),
-
-    if
-        Connect ->
-            case Started of
-                {ok, Pid} ->
-                    case gen_server:call(Pid, {connect, ProtocolFactory}) of
-                        ok ->
-                            {ok, Pid};
-                        Error ->
-                            Error
-                    end;
-                Else ->
-                    Else
-            end;
-        true ->
-            Started
+new(Protocol, Service)
+  when is_atom(Service) ->
+    {ok, #tclient{protocol = Protocol,
+                  service = Service,
+                  seqid = 0}}.
+
+-spec call(#tclient{}, atom(), list()) -> {#tclient{}, {ok, term()} | {error, term()}}.
+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.
 
--spec call(term(), atom(), list()) -> {ok, term()} | {error, term()}.
-call(Client, Function, Args)
-  when is_pid(Client), is_atom(Function), is_list(Args) ->
-    case gen_server:call(Client, {call, Function, Args}) of
-        R = {ok, _} -> R;
-        R = {error, _} -> R;
-        {exception, Exception} -> throw(Exception)
-    end.
-
--spec cast(term(), atom(), list()) -> ok.
-cast(Client, Function, Args)
-  when is_pid(Client), is_atom(Function), is_list(Args) ->
-    gen_server:cast(Client, {call, Function, Args}).
 
 %% Sends a function call but does not read the result. This is useful
 %% if you're trying to log non-oneway function calls to write-only
 %% transports like thrift_disk_log_transport.
--spec send_call(term(), atom(), list()) -> ok.
-send_call(Client, Function, Args)
-  when is_pid(Client), is_atom(Function), is_list(Args) ->
-    gen_server:call(Client, {send_call, Function, Args}).
-
--spec close(term()) -> ok.
-close(Client) when is_pid(Client) ->
-    gen_server:cast(Client, close).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%%                         {ok, State, Timeout} |
-%%                         ignore               |
-%%                         {stop, Reason}
-%% Description: Initiates the server
-%%--------------------------------------------------------------------
-init([Service, Opts]) ->
-    case lists:keysearch(tether, 1, Opts) of
-        {value, {tether, Pid}} ->
-            erlang:monitor(process, Pid);
-        _Else ->
-            ok
-    end,
-    {ok, #state{service = Service}}.
-
-%%--------------------------------------------------------------------
-%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
-%%                                      {reply, Reply, State, Timeout} |
-%%                                      {noreply, State} |
-%%                                      {noreply, State, Timeout} |
-%%                                      {stop, Reason, Reply, State} |
-%%                                      {stop, Reason, State}
-%% Description: Handling call messages
-%%--------------------------------------------------------------------
-handle_call({connect, ProtocolFactory}, _From,
-            State = #state{service = Service}) ->
-    case ProtocolFactory() of
-        {ok, Protocol} ->
-            {reply, ok, State#state{protocol = Protocol,
-                                    seqid = 0}};
-        Error ->
-            {stop, normal, Error, State}
-    end;
-
-handle_call({call, Function, Args}, _From, State = #state{service = Service}) ->
-    Result = catch_function_exceptions(
-               fun() ->
-                       ok = send_function_call(State, Function, Args),
-                       receive_function_result(State, Function)
-               end,
-               Service),
-    {reply, Result, State};
-
-
-handle_call({send_call, Function, Args}, _From, State = #state{service = Service}) ->
-    Result = catch_function_exceptions(
-               fun() ->
-                       send_function_call(State, Function, Args)
-               end,
-               Service),
-    {reply, Result, State}.
-
-
-%% Helper function that catches exceptions thrown by sending or receiving
-%% a function and returns the correct response for call or send_only above.
-catch_function_exceptions(Fun, Service) ->
-    try
-        Fun()
-    catch
-        throw:{return, Return} ->
-            Return;
-          error:function_clause ->
-            ST = erlang:get_stacktrace(),
-            case hd(ST) of
-                {Service, function_info, [Function, _]} ->
-                    {error, {no_function, Function}};
-                _ -> throw({error, {function_clause, ST}})
-            end
-    end.
-
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%%                                      {noreply, State, Timeout} |
-%%                                      {stop, Reason, State}
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
-handle_cast({call, Function, Args}, State = #state{service = Service,
-                                                   protocol = Protocol,
-                                                   seqid = SeqId}) ->
-    _Result =
-        try
-            ok = send_function_call(State, Function, Args),
-            receive_function_result(State, Function)
-        catch
-            Class:Reason ->
-                error_logger:error_msg("error ignored in handle_cast({cast,...},...): ~p:~p~n", [Class, Reason])
-        end,
-
-    {noreply, State};
-
-handle_cast(close, State=#state{protocol = Protocol}) ->
-%%     error_logger:info_msg("thrift_client ~p received close", [self()]),
-    {stop,normal,State};
-handle_cast(_Msg, State) ->
-    {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_info(Info, State) -> {noreply, State} |
-%%                                       {noreply, State, Timeout} |
-%%                                       {stop, Reason, State}
-%% Description: Handling all non call/cast messages
-%%--------------------------------------------------------------------
-handle_info({'DOWN', MonitorRef, process, Pid, _Info}, State)
-  when is_reference(MonitorRef), is_pid(Pid) ->
-    %% We don't actually verify the correctness of the DOWN message.
-    {stop, parent_died, State};
-
-handle_info(_Info, State) ->
-    {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> void()
-%% Description: This function is called by a gen_server when it is about to
-%% terminate. It should be the opposite of Module:init/1 and do any necessary
-%% cleaning up. When it returns, the gen_server terminates with Reason.
-%% The return value is ignored.
-%%--------------------------------------------------------------------
-terminate(Reason, State = #state{protocol=undefined}) ->
-    ok;
-terminate(Reason, State = #state{protocol=Protocol}) ->
-    thrift_protocol:close_transport(Protocol),
-    ok.
+-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).
+
+-spec close(#tclient{}) -> ok.
+close(#tclient{protocol=Protocol}) ->
+    thrift_protocol:close_transport(Protocol).
 
-%%--------------------------------------------------------------------
-%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% Description: Convert process state when code is changed
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
 
 %%--------------------------------------------------------------------
 %%% Internal functions
 %%--------------------------------------------------------------------
-send_function_call(#state{protocol = Proto,
-                          service  = Service,
-                          seqid    = SeqId},
+-spec send_function_call(#tclient{}, atom(), list()) -> {#tclient{}, ok | {error, term()}}.
+send_function_call(Client = #tclient{protocol = Proto,
+                                     service  = Service,
+                                     seqid    = SeqId},
                    Function,
                    Args) ->
     Params = Service:function_info(Function, params_type),
-    {struct, PList} = Params,
-    if
-        length(PList) =/= length(Args) ->
-            throw({return, {error, {bad_args, Function, Args}}});
-        true -> ok
-    end,
-
-    Begin = #protocol_message_begin{name = atom_to_list(Function),
-                                    type = ?tMessageType_CALL,
-                                    seqid = SeqId},
-    ok = thrift_protocol:write(Proto, Begin),
-    ok = thrift_protocol:write(Proto, {Params, list_to_tuple([Function | Args])}),
-    ok = thrift_protocol:write(Proto, message_end),
-    thrift_protocol:flush_transport(Proto),
-    ok.
-
-receive_function_result(State = #state{protocol = Proto,
-                                       service = Service},
-                        Function) ->
+    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},
+            ok = thrift_protocol:write(Proto, Begin),
+            ok = thrift_protocol:write(Proto, {Params, list_to_tuple([Function | Args])}),
+            ok = thrift_protocol:write(Proto, message_end),
+            ok = thrift_protocol:flush_transport(Proto),
+            {Client, ok}
+    end.
+
+-spec receive_function_result(#tclient{}, atom()) -> {#tclient{}, {ok, term()} | {error, term()}}.
+receive_function_result(Client = #tclient{service = Service}, Function) ->
     ResultType = Service:function_info(Function, reply_type),
-    read_result(State, Function, ResultType).
+    read_result(Client, Function, ResultType).
 
-read_result(_State,
-            _Function,
-            oneway_void) ->
-    {ok, ok};
+read_result(Client, _Function, oneway_void) ->
+    {Client, {ok, ok}};
 
-read_result(State = #state{protocol = Proto,
-                           seqid    = SeqId},
+read_result(Client = #tclient{protocol = Proto,
+                              seqid    = SeqId},
             Function,
             ReplyType) ->
     case thrift_protocol:read(Proto, message_begin) of
         #protocol_message_begin{seqid = RetSeqId} when RetSeqId =/= SeqId ->
-            {error, {bad_seq_id, SeqId}};
+            {Client, {error, {bad_seq_id, SeqId}}};
 
         #protocol_message_begin{type = ?tMessageType_EXCEPTION} ->
-            handle_application_exception(State);
+            handle_application_exception(Client);
 
         #protocol_message_begin{type = ?tMessageType_REPLY} ->
-            handle_reply(State, Function, ReplyType)
+            handle_reply(Client, Function, ReplyType)
     end.
 
-handle_reply(State = #state{protocol = Proto,
-                            service = Service},
+
+handle_reply(Client = #tclient{protocol = Proto,
+                               service = Service},
              Function,
              ReplyType) ->
     {struct, ExceptionFields} = Service:function_info(Function, exceptions),
     ReplyStructDef = {struct, [{0, ReplyType}] ++ ExceptionFields},
     {ok, Reply} = thrift_protocol:read(Proto, ReplyStructDef),
+    ok = thrift_protocol:read(Proto, message_end),
     ReplyList = tuple_to_list(Reply),
     true = length(ReplyList) == length(ExceptionFields) + 1,
     ExceptionVals = tl(ReplyList),
     Thrown = [X || X <- ExceptionVals,
                    X =/= undefined],
-    Result =
-        case Thrown of
-            [] when ReplyType == {struct, []} ->
-                {ok, ok};
-            [] ->
-                {ok, hd(ReplyList)};
-            [Exception] ->
-                {exception, Exception}
-        end,
-    ok = thrift_protocol:read(Proto, message_end),
-    Result.
+    case Thrown of
+        [] when ReplyType == {struct, []} ->
+            {Client, {ok, ok}};
+        [] ->
+            {Client, {ok, hd(ReplyList)}};
+        [Exception] ->
+            throw({Client, {exception, Exception}})
+    end.
 
-handle_application_exception(State = #state{protocol = Proto}) ->
-    {ok, Exception} = thrift_protocol:read(Proto,
-                                           ?TApplicationException_Structure),
+handle_application_exception(Client = #tclient{protocol = Proto}) ->
+    {ok, Exception} =
+        thrift_protocol:read(Proto, ?TApplicationException_Structure),
     ok = thrift_protocol:read(Proto, message_end),
     XRecord = list_to_tuple(
                 ['TApplicationException' | tuple_to_list(Exception)]),
     error_logger:error_msg("X: ~p~n", [XRecord]),
     true = is_record(XRecord, 'TApplicationException'),
-    {exception, XRecord}.
+    throw({Client, {exception, XRecord}}).

Added: incubator/thrift/trunk/lib/erl/src/thrift_client_util.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/erl/src/thrift_client_util.erl?rev=990979&view=auto
==============================================================================
--- incubator/thrift/trunk/lib/erl/src/thrift_client_util.erl (added)
+++ incubator/thrift/trunk/lib/erl/src/thrift_client_util.erl Mon Aug 30 22:05:29 2010
@@ -0,0 +1,61 @@
+%%
+%% 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_client_util).
+
+-export([new/4]).
+
+%%
+%% Splits client options into client, protocol, and transport options
+%%
+%% split_options([Options...]) -> {ProtocolOptions, TransportOptions}
+%%
+split_options(Options) ->
+    split_options(Options, [], []).
+
+split_options([], ProtoIn, TransIn) ->
+    {ProtoIn, TransIn};
+
+split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
+  when OptKey =:= strict_read;
+       OptKey =:= strict_write ->
+    split_options(Rest, [Opt | ProtoIn], TransIn);
+
+split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
+  when OptKey =:= framed;
+       OptKey =:= connect_timeout;
+       OptKey =:= sockopts ->
+    split_options(Rest, ProtoIn, [Opt | TransIn]).
+
+
+%% Client constructor for the common-case of socket transports
+%% with the binary protocol
+new(Host, Port, Service, Options)
+  when is_integer(Port), is_atom(Service), is_list(Options) ->
+    {ProtoOpts, TransOpts} = split_options(Options),
+
+    {ok, TransportFactory} =
+        thrift_socket_transport:new_transport_factory(Host, Port, TransOpts),
+
+    {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
+                              TransportFactory, ProtoOpts),
+
+    {ok, Protocol} = ProtocolFactory(),
+
+    thrift_client:new(Protocol, Service).

Modified: incubator/thrift/trunk/test/erl/Makefile
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/erl/Makefile?rev=990979&r1=990978&r2=990979&view=diff
==============================================================================
--- incubator/thrift/trunk/test/erl/Makefile (original)
+++ incubator/thrift/trunk/test/erl/Makefile Mon Aug 30 22:05:29 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_disklog test_membuffer
 
 INCLUDES = 
 TARGETS = $(patsubst %,${TARGETDIR}/%.beam,${MODULES})

Modified: incubator/thrift/trunk/tutorial/erl/client.erl
URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/tutorial/erl/client.erl?rev=990979&r1=990978&r2=990979&view=diff
==============================================================================
--- incubator/thrift/trunk/tutorial/erl/client.erl (original)
+++ incubator/thrift/trunk/tutorial/erl/client.erl Mon Aug 30 22:05:29 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.