I'm using gproc_pool for simple process pooling and I'm running in to an issue when trying make things synchronous for some property-based testing of my project.
Is there a way to make sure that there is room for a new worker after a worker has been removed from a pool? I made simple waiting function that just keeps polling defined_workers/1 until the worker is gone (I also tried worker_pool/1).
I have boiled down my issue to a runnable eunit test:
gproc_pool_add_worker_race_test() ->
ok = application:ensure_started(gproc),
ok = gproc_pool:new(my_pool, direct, [{size, 1}, {auto_size, false}]),
[] = gproc_pool:defined_workers(my_pool),
Pos1 = gproc_pool:add_worker(my_pool, worker1),
[{worker1, Pos1, 0}] = gproc_pool:defined_workers(my_pool),
Pid = spawn(fun() ->
true = gproc_pool:connect_worker(my_pool, worker1),
receive after 100 -> bye end
end),
Monitor = monitor(process, Pid),
receive
{'DOWN', Monitor, process, _, _} -> ok
end,
true = gproc_pool:remove_worker(my_pool, worker1),
wait_until_worker_is_removed_from_pool(my_pool, worker1),
[] = gproc_pool:defined_workers(my_pool), %% the pool seems to be empty
Pos2 = gproc_pool:add_worker(my_pool, worker2), %% throws error:pool_full
true = is_integer(Pos2).
wait_until_worker_is_removed_from_pool(Pool, Name) ->
case lists:keymember(Name, 1, gproc_pool:defined_workers(Pool)) of
false -> ok;
true ->
receive
after 200 -> wait_until_worker_is_removed_from_pool(Pool, Name)
end
end.
I'm using gproc_pool for simple process pooling and I'm running in to an issue when trying make things synchronous for some property-based testing of my project.
Is there a way to make sure that there is room for a new worker after a worker has been removed from a pool? I made simple waiting function that just keeps polling
defined_workers/1
until the worker is gone (I also triedworker_pool/1
).I have boiled down my issue to a runnable eunit test: