uwiger / gproc

Extended process registry for Erlang
Apache License 2.0
1.07k stars 232 forks source link

gproc_pool round_robin is broken a bit #170

Closed abogosyan closed 5 years ago

abogosyan commented 5 years ago

When one of workers is disconnected, one of the rest is selected twice in RR cycle, test code:

    gproc_pool:new(p),
    gproc_pool:add_worker(p, w1),
    gproc_pool:add_worker(p, w2),
    gproc_pool:add_worker(p, w3),
    Work = fun(W) -> spawn(fun() -> gproc_pool:connect_worker(p, W), fun F() -> F() end() end) end,
    W1 = Work(w1),
    W2 = Work(w2),
    W3 = Work(w3),
    timer:sleep(100),
    ?assertEqual([W1, W2, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]),
    ?assertEqual([W1, W2, W3, W1, W2, W3, W1, W2, W3], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]),
    exit(W2, die),
    timer:sleep(100),
    ?assertEqual([W1, W3], [ P || {_, P} <- gproc_pool:active_workers(p)]),
    ?assertEqual([W1, W3, W1, W3, W1, W3, W1, W3, W1], [gproc_pool:pick_worker(p) || _ <- lists:seq(1, 9)]), %% fails, got: [W1, W3, W3, W1, W3, W3, W1, W3, W3]

The problem is at: https://github.com/uwiger/gproc/blob/master/src/gproc_pool.erl#L362, should be Diff when Diff > 0. This will fix cases for exit(W2, die) and exit(W1, die), disconnecting last worker (W3) works as expected

abogosyan commented 5 years ago

Created MR: https://github.com/uwiger/gproc/pull/171

abogosyan commented 5 years ago

thx! :)