fsm and networks

Dustin Sallings <>
Sat May 1 11:09:26 CEST 2004


	I'm implementing a process that speaks the postgres FE/BE protocol.  
gen_fsm seemed like the right thing to do, but I'm having a problem 
that's leading me to believe I'm doing something wrong.

	Postgres' protocol is one in which the client speaks first, so I 
basically do the following in my init/1:

     ok = gen_tcp:send(Socket, makeString(Announcement)),
     {ok, connected, #pginfo{conninfo=Conninfo, socket=Socket,
         sstat=dict:new()}}.

	From there, I get a message via handle_info/3, which I deal with in 
the following way:

handle_info({tcp, _Port, Data}, State, Info) ->
     handle_packet(Data, State, Info).

dealWithRemaining([Type|Data], State, Info) ->
     gen_fsm:send_event(self(), {data_arrived, Type, Data});
dealWithRemaining([], _State, _Info) ->
     [].

handle_packet([Type|Data], State, Info) ->
     {Len, Rest} = getInt32(Data),
     {FullData, Extra} = getAllData(Len-4, Rest, Info),
     assert(length(FullData)+4 == Len, "Incorrect data length"),
     dealWithRemaining(Extra, State, Info),
     handle_packet(Type, Len, FullData, State, Info).

	This works just fine except in a couple of circumstances.  For one, I 
don't quite know how to tell (or preferably wait until) I'm in the 
right state to issue queries.  I am not ready after init is finished.  
The server will send me an authentication request of some sort, I 
respond (via a handle_packet/5), and the server sends a few more things 
over and eventually a command letting me know it's ready to accept 
queries.  Ideally, init could block while this stuff occurs, but a 
variety of commands could arrive before the server's ready.

	Similarly, I have the following:

execute(Fsm, Query) ->
     gen_fsm:sync_send_event(Fsm,{execute,Query}).

and its corresponding

ready_for_query({execute, Query}, Pid, Info) ->
     io:format("Executing query:  ~p~n", [Query]),
     ok = gen_tcp:send(Info#pginfo.socket, [$Q|makeString(Query ++ 
"\0")]),
     {reply, ok, query_pending, Info}.

	I'm not sure how to go about getting the results from this query.  
Right now, I just return, and let the handle_packet/5 print out the 
various stuff the DB sends back.

	Any ideas on how to do this stuff?

--
SPY                      My girlfriend asked me which one I like better.
pub  1024/3CAE01D5 1994/11/03 Dustin Sallings <>
|    Key fingerprint =  87 02 57 08 02 D0 DA D6  C8 0F 3E 65 51 98 D8 BE
L_______________________ I hope the answer won't upset her. ____________




More information about the erlang-questions mailing list