erlang-redis
erlang-redis copied to clipboard
Try process all data in reply buffer before accepting new replies
redis_client
does not handle cases where the redis server sends a batch reply. Details to reproduce the problem below:
1> {ok, Conn} = redis:connect(). % connect to the redis server
{ok,<0.34.0>}
2> sys:get_state(Conn). % confirm the state is clean
{state,#Port<0.718>,
{[],[]},
{unknown,<<>>},
undefined,<0.32.0>}
3> [ spawn(fun() -> io:format("~p~n", [redis:ping(Conn)]) end) || _ <- lists:seq(1,3) ]. % run 3 requests
[<0.39.0>,<0.40.0>,<0.41.0>]
pong
4> sys:get_state(Conn). % state holds the last 2 replies in buffer
{state,#Port<0.718>,
{[{<0.41.0>,#Ref<0.0.0.47>}],[{<0.40.0>,#Ref<0.0.0.45>}]},
{unknown,<<"+PONG\r\n+PONG\r\n">>},
undefined,<0.32.0>}
5> spawn(fun() -> io:format("~p~n", [redis:get(Conn, "some_key")]) end). % send a different request
<0.44.0>
pong
6> sys:get_state(Conn). % state releases PONG number 2, and holds the reply for the GET request
{state,#Port<0.718>,
{[{<0.44.0>,#Ref<0.0.0.58>}],[{<0.41.0>,#Ref<0.0.0.47>}]},
{unknown,<<"+PONG\r\n$-1\r\n">>},
undefined,<0.32.0>}
redis_client
should try to process all replies in its buffer before accepting new replies from the server.