dashbitco / nimble_pool

A tiny resource-pool implementation for Elixir
347 stars 20 forks source link

Multiple instances of PortPool in the README have conflicts #41

Closed jackalcooper closed 8 months ago

jackalcooper commented 8 months ago

the tests passes but it raises error below if there are two instances of the port pool.

22:28:03.346 [error] Error during PortPool.terminate_worker/3 callback:
** (ArgumentError) argument error
    :erlang.port_close(#Port<0.19>)
    test/pool_rep_test.exs:74: PortPool.terminate_worker/3
    (nimble_pool 1.0.0) lib/nimble_pool.ex:932: NimblePool.do_apply_worker_callback/4
    (nimble_pool 1.0.0) lib/nimble_pool.ex:867: NimblePool.maybe_terminate_worker/3
    (nimble_pool 1.0.0) lib/nimble_pool.ex:610: anonymous fn/4 in NimblePool.terminate/2
    (elixir 1.15.5) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
    (nimble_pool 1.0.0) lib/nimble_pool.ex:609: NimblePool.terminate/2
    (stdlib 5.0.2) gen_server.erl:1125: :gen_server.try_terminate/3
    (stdlib 5.0.2) gen_server.erl:1321: :gen_server.terminate/10
    (stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
defmodule PoolTest do
  use ExUnit.Case, async: true

  test "naive pool" do
    child = {NimblePool, worker: {PortPool, :cat}, name: PortPool}
    Supervisor.start_link([child], strategy: :one_for_one)

    for i <- 0..10000 do
      PortPool.command(PortPool, "hello#{i}\n")
    end
  end

  test "naive pool 2" do
    child = {NimblePool, worker: {PortPool, :cat}, name: PortPool2}
    Supervisor.start_link([child], strategy: :one_for_one)

    for i <- 0..10000 do
      PortPool.command(PortPool2, "hello#{i}\n")
    end
  end
end
josevalim commented 8 months ago

It is not related to multiple entries, just a race with the parent process linked. If you use a sleep in the second test it could still reproduce it :)