Skip to content

Add ability to expire resources within the pool #216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from

Conversation

syeopite
Copy link

Closes #47

This PR implements the ability to expire assets within the pool based on what I think was discussed in #47

This is configured through the two new pool parameters max_lifetime_per_resource and max_idle_time_per_resource which sets the number of seconds before they get expired and removed from the pool. This is done on each #checkout and #release but also with an optional background fiber which runs on either a configured timer, or whichever configured expiration is shorter.

This PR mostly also respects initial_pool_size in that it'll try to keep at least that many resources within the pool--but it doesn't actually know which resources are stale until it checks on a #checkout/#release or with the background fiber so they're not necessarily always fresh.

But if any of the expiration check causes the amount of resources within pool to drop below initial_pool_size it'll immediately replenish with fresh resources till its back up to initial_pool_size.

Also when a #checkout internally finds an expired resource, the new PoolResourceExpired exception is raised. So #retry will get more important.

The specs all seems to pass and modifying the manual specs to use the new expiration features did not show any glaring problems either.

Please let me know if I've missed something with this implementation! I wrote this over the course of a single night so apologies in advance if the code might be a bit messy 😅

syeopite added 21 commits May 22, 2025 23:20
Structs are passed by value meaning that the last_checked_out recorded
never actually gets updated
The number of inflight resources was not properly incremented or
compared against resulting in the possibility of fibers queuing up
many unnecessary replenishments to the pool.
Allow integer arguments for max expiration time
Allow using `Time::Span` for the resource sweeper timer
Replace call to Time::Span.positive?

Bumps some tiny sleep duration to safeguard test succcess
Although handled by `PoolResourceLost(T)` doing so manually avoids
a mutex lock and a second redundant call to #delete
elsif can_increase_idle_pool
# Checks lifetime expiration and updates last checked out time
# Old idle expiration isn't checked because this replaces it.
expire_info = @resource_lifecycle[resource]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also technically a breaking change in that it'll now raise when a non pool item is released into the pool


return if replenish <= 0

replenish.times do |index|
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resource replenishment could actually block a checkout/release operation for a really long time depending on how many resources it needs to be built. In most cases it should just be a single one but it can quickly balloon when many resources are discarded manually from outside of the pool. I'm not entirely sure what's the best way to resolve this.

I feel like spawning a new fiber each time is excessive, so maybe it could be dispatched to the already existing background job?

There's also the fact that any non-blocking operation will remove the guarantee of there always being at least initial_pool_size fresh resources available...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add an option to check for liveness on checkout
1 participant