mccoy / medici

Erlang interface for Tokyo Tyrant
27 stars 11 forks source link

principe hijacks the process mailbox #2

Open ghost opened 13 years ago

ghost commented 13 years ago

principe:tyrant_response incorrectly assumes that principe is the only thing sending messages to the mailbox. I'm attaching a test case which demonstrates this bug, as well as a patch that fixes it. This problem may occur in principe_table and/or medici; I haven't investigated those yet.

ghost commented 13 years ago

github doesn't support attachments? How lame.

Here's the test:

-module(principe_test).
-export([runtest/0, loop/0]).

mongod() -> "mongod".

runtest() ->
    start_mongo(),
    Inserter = spawn_link( fun ?MODULE:loop/0 ),
    Inserter ! quit,
    Inserter ! go,
    timer:sleep(500),
    {ok, Fd} = file:open("mongod.pid",[read]),
    {ok, Data} = file:read_line( Fd ),
    os:cmd(io_lib:format("kill -HUP ~p",[string:strip(Data,both,10)])).

start_mongo() ->
    filelib:ensure_dir("test/file"),
    Cmd = io_lib:format(
        "~s --dbpath ~s --port 9999 --fork --logpath ~s --pidfilepath ~s", 
        [   mongod(),
            filename:absname("test"), 
            filename:absname("mongod.log"), 
            filename:absname("mongod.pid") ]),
    os:cmd(Cmd),
    timer:sleep(1000).

loop() ->
    {ok, P} = principe:connect( [{port, 9999}] ),
    receive
        go -> principe:put( P, "key", "value" )
    end.

and here's the patch:

diff --git a/src/principe.erl b/src/principe.erl
--- a/src/principe.erl
+++ b/src/principe.erl
@@ -718,7 +718,7 @@
            {error, conn_closed};
         {tcp_error, _, _} -> 
            {error, conn_error};
-        Data -> 
+    {tcp, _, _} = Data ->
            ResponseHandler(Data)
     after ?TIMEOUT -> 
            {error, timeout}