zeromq / erlzmq2

Erlang binding for 0MQ (v2)
http://zeromq.org/
MIT License
164 stars 63 forks source link

When using a timeout when calling erlzmq:recv () can lose a message #61

Open dmelnik opened 11 years ago

dmelnik commented 11 years ago

If the messages in the queue at the time of the call is not, but it it appears after the timeout, it is lost This occurs because the timeout is implemented using receive ... after, and the message that it is obtained when the timeout has passed, there is no one to accept the message, and it remains in the queue process

(a similar situation with erlzmq:send (), but it returns {error, eagain}, even though the message was sent)

test case:

zmq_recv_error() -> {ok, C} = erlzmq:context(), {ok, BS} = erlzmq:socket(C, [pull]), ok = erlzmq:setsockopt(BS, rcvtimeo, 1000), ok = erlzmq:bind(BS, "tcp://127.0.0.1:5555"), spawn_link( fun() -> {ok, C2} = erlzmq:context(), {ok, CS2} = erlzmq:socket(C2, [push]), ok = erlzmq:connect(CS2, "tcp://127.0.0.1:5555"), timer:sleep(1500), ok = erlzmq:send(CS2, <<"some data">>), ok = erlzmq:close(CS2), ok = erlzmq:term(C2) end), case erlzmq:recv(BS) of {error, eagain} -> io:format("error:~p~n", [eagain]), case erlzmq:recv(BS) of {error, eagain} -> io:format("error:~p~n", [eagain]), io:format("~nERROR!~n"); {ok, Data} -> io:format("data:~p~n", [Data]), io:format("~nOK~n") end; {ok, Data} -> io:format("data:~p~n", [Data]), io:format("OK~n") end.

yrashk commented 10 years ago

cc @okeuday: have you experienced anything like this?

okeuday commented 10 years ago

i think this is a problem when not using active receives... so a problem with passive receives and all sends. The timeout being at: https://github.com/zeromq/erlzmq2/blob/master/src/erlzmq.erl#L189 https://github.com/zeromq/erlzmq2/blob/master/src/erlzmq.erl#L254 I think this behaviour is by-design, it must timeout, so there isn't a better option I am aware of. If this behaviour is a concern, the timeout can always be set to be blocking (a timeout of infinity). When this problem does occur, the process will still get the message later, but it will remain unhandled and possibly ignored.