I’ve been working on a pool of remote sessions, where each session is created and closed with HTTP requests. Sessions are limited in number, so I figured, why not implement a pool? An additional requirement is that these sessions must be refreshed every 15 minutes if idle.
I decided to use a GenServer to handle the sessions. When it starts, it makes a request to create a session and stores the secret. On termination, it makes another request to close the session. It has a public API that makes an HTTP request using the session, parses the response, and sends it back to the client. And if it’s not used for 15 minutes, it’ll refresh the session itself.
To manage the pool, I’ve got a Supervisor looking after two children:
- Finch HTTP pool
- Poolboy worker pool
So when a Poolboy worker needs to make a request, it grabs a connection from the Finch HTTP pool. However, things start to go south when it’s time to shut everything down.
When the app needs to shut down, the Supervisor sends a shutdown signal to Poolboy. But it seems Poolboy isn’t that patient and doesn’t wait for its children to stop. From what I can tell, the exit/2
function works asynchronously. So, the children get the shutdown signal, but the Poolboy worker pool doesn’t stick around.
Then the Finch pool shuts down, the Supervisor follows suit, and finally, the workers. But, here’s the twist: the workers need the Finch pool to send out a final request to close the remote session. So, they crash without closing the remote sessions.
What’s throwing me for a loop is why a library as popular as Poolboy would behave like this. Am I missing something here?
I also thought about using NimblePool, but decided against it because:
NimblePool may not be a good option to manage processes. After all, the goal of NimblePool is to avoid creating processes for resources. If you already have a process, using a process-based pool such as
poolboy
will provide a better abstraction.
Any ideas on this? Maybe a different approach?
PD: I opened an issue in Poolex