Skip to content

pool_max_idle_time doesn't shut down empty pools #311

Description

@PragTob

(Split this out of #309 )

Problem

As detailed of #309 (there is a script showcasing this) we have an issue where even with pool_max_idle_time set we still have process leakage. I just found exactly why that is, in the docs of NimblePool.handle_ping/2 there is a disclaimer:

On lazy pools, if no worker is currently on the pool the callback will never be called. Therefore you can not rely on this callback to terminate empty lazy pools.

Finch is using lazy pools, starting a bunch of empty ones in the beginning (depending on pool count). If they never get a connection, they'll never be shut down.

The relevant code in NimblePool it's here:

  defp do_check_idle_resources(resources, now_in_ms, state, new_resources, remaining_pings) do
    case :queue.out(resources) do
      {:empty, _} ->
        {:ok, new_resources, state}

This isn't a problem when you know where your HTTP requests go. In my use case, I can't know where my HTTP requests will go in advance, there are infinite possibilities, and I need my default pool to be decently large as some of these will have a lot of traffic.

Solutions

I'm not sure about the best solution here, here are some rough ideas:

  • We could ask/contribute to nimble_pool an option to shut down empty pools, then the pools would shut down
  • we could implement a strategy to shut down empty pools ourselves, feels a bit sad though (as NimblePool already has a ping mechanic)

That said, with the current workings I'm also a bit worried about shutting down pools. If I'm not missing anything, let's say you configure a pool count of 15. You may shut down 14 pools via idle verification, one survives and now if a load spike comes that one pool has to deal with all the traffic as no new pools are started again. With a set count of pools in a... pool group (? not sure how to call it) it may be better to shut down all pools at once or none at all to avoid the scenario described.

That'd be different though if we used dynamic pool creation & closure - might open another issue about that though.

I'm happy to open an issue at NimblePool and suggest the change, but so far it seems very deliberate on their part. So, I'd first like to align on a way forward here.


As always, thank you a ton for providing us all with great and free open source software! 💚 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions