Codexportfolio intelligence

@philiprehberger/rb-pool

Generic thread-safe object pool with idle timeout and health checks

RubyRubyGems

Capabilities

README

philiprehberger-pool

Tests Gem Version Last updated

philiprehberger-pool

Generic thread-safe object pool with idle timeout and health checks

Requirements

  • Ruby >= 3.1

Installation

Add to your Gemfile:

gem "philiprehberger-pool"

Or install directly:

gem install philiprehberger-pool

Usage

require "philiprehberger/pool"

# Create a pool of database connections
pool = Philiprehberger::Pool.new(size: 5, timeout: 10) do
  SomeDatabase.connect(host: 'localhost')
end

# Automatic checkout/checkin with a block
pool.with do |conn|
  conn.query('SELECT 1')
end

# Manual checkout/checkin
conn = pool.checkout
begin
  conn.query('SELECT 1')
ensure
  pool.checkin(conn)
end

Health Checks

pool = Philiprehberger::Pool.new(
  size: 5,
  timeout: 10,
  health_check: ->(conn) { conn.ping }
) { SomeDatabase.connect }

Idle Timeout

pool = Philiprehberger::Pool.new(
  size: 5,
  idle_timeout: 60
) { SomeDatabase.connect }

Pool Stats

pool.stats
# => { size: 2, available: 1, in_use: 1, max: 5, waiting: 0 }

# Fraction of max currently in use (0.0..1.0)
pool.utilization  # => 0.2

# Threads currently blocked on checkout (back-pressure indicator)
pool.waiting      # => 0

Pruning Idle Resources

pool = Philiprehberger::Pool.new(size: 5, idle_timeout: 60) { TCPSocket.new("db.local", 5432) }

# Periodically reclaim idle handles without waiting for the next checkout
pruned = pool.prune_idle  # => count of resources evicted

Draining Idle Resources

require "philiprehberger/pool"

pool = Philiprehberger::Pool.new(size: 5) { TCPSocket.new("db.local", 5432) }

# Rotate connections after a config change
drained = pool.drain  # => closes idle connections, returns count
# New checkouts will create fresh connections

Clearing Idle Resources

require "philiprehberger/pool"

pool = Philiprehberger::Pool.new(size: 10) { build_db_connection(creds.current) }

# Credentials rotated — discard every cached connection without tearing down the pool
cleared = pool.clear  # => count of idle resources destroyed; checked-out ones are untouched
# Subsequent checkouts will lazily build fresh connections using the new credentials

Shutdown

pool.shutdown
pool.shutdown? # => true

API

Philiprehberger::Pool.new(size:, timeout: 5, idle_timeout: nil, health_check: nil, &factory)

Creates a new resource pool.

ParameterDescription
sizeMaximum number of resources
timeoutSeconds to wait for a resource (default: 5)
idle_timeoutSeconds before idle resources are evicted (default: nil)
health_checkLambda called with resource, must return truthy (default: nil)
&factoryBlock that creates a new resource

Instance Methods

MethodDescription
#with { |resource| ... }Checkout, yield, and auto-checkin
#checkout(timeout: nil)Manually check out a resource
#checkin(resource)Return a resource to the pool
#drainRemove and close idle resources, return count drained
#statsHash with :size, :available, :in_use, :max, :waiting (threads blocked on checkout)
#waitingNumber of threads currently blocked in checkout/with waiting for a resource
#utilizationFraction of max capacity currently in use (0.0..1.0)
#sizeConfigured maximum capacity
#prune_idleEvict available resources past idle_timeout, return count
#clearDestroy every idle resource, leave checked-out ones; return count
#shutdownClose all resources, reject new checkouts
#shutdown?Whether the pool has been shut down

Errors

ErrorDescription
Pool::TimeoutErrorCheckout timed out waiting for a resource
Pool::ShutdownErrorOperation attempted on a shut-down pool

Development

bundle install
bundle exec rspec
bundle exec rubocop

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT