my socket can't handle the load
Pablo Platt
pablo.platt@REDACTED
Wed Jun 2 17:27:40 CEST 2010
Hi,
I'm writing a driver to a database that is using a tcp socket.
There are two types of messages, "send and forget" and "send and receive".
I have a gen_server that is responsible for opening the socket, receive a message from a process and sending it to the socket and receive responses and pass them to the caller.
The gen_server saves a list of {request_id, CallerPid} in the state to know who to respond to when a packet is received from the db.
Everything works when the rate of messages is low but when increasing it I'm starting to get gen_server timeout error on the requestor.
Do I need to add/change parameters when opening the socket?
Should I queue requests and wait for a response before sending the next request or is it ok to send several requests one after the other?
Thanks
The client sends a request using either:
Resp = gen_server:call(Conn, {request, Request})
or
gen_server:cast(Conn, {request, Request})
The relevant gen_server code:
init([Host, Port]) ->
Socket = open_socket(Host, Port),
{ok, #state{socket=Socket, req_id=1}}.
open_socket(Host, Port) ->
case gen_tcp:connect(Host, Port, [binary, {active, true}]) of
{ok, Sock} ->
Sock;
{error, Reason} ->
exit({open_socket_failed, Reason})
end.
handle_call({request, Packet}, From, State) ->
ReqID = State#state.req_id + 1,
gen_tcp:send(State#state.socket, Packet),
{noreply, State#state{req_id=ReqID, requests=[{ReqID, From}|State#state.requests]}};
handle_cast({request, Packet}, State) ->
ReqID = State#state.req_id + 1,
gen_tcp:send(State#state.socket, Packet),
{noreply, State#state{req_id=ReqID}}.
handle_info({tcp, _Socket, Data}, State) ->
RawResp = <<(State#state.resp)/binary, Data/binary>>,
case check_packet:decode_response(RawResp) of
undefined ->
{noreply, State#state{resp = RawResp}};
{Resp, Tail} ->
ResponseTo = get_requestor(Resp),
{value, {ResponseTo, Client}, NewRequests} = lists:keytake(ResponseTo, 1, State#state.requests),
gen_server:reply(Client, Resp),
{noreply, State#state{resp = Tail, requests=NewRequests}}
end;
% the following never been called, even when I'm getting the error.
handle_info({tcp_closed, _Socket}, State) ->
{noreply, State};
handle_info({tcp_error, _Socket, _Reason}, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
More information about the erlang-questions
mailing list