Generic resource pooling system for managing limited resources with automatic queueing and lifecycle management. Perfect for connection pools, object pools, or any scenario where you need to limit concurrent resource usage.
The pool module provides a coroutine-safe way to manage a limited number of resources. When all resources are in use, requests are automatically queued and resumed when a resource becomes available.
Create a new resource pool.
Parameters:
arg_map (table, optional): Configuration table with callbacks
onnew (function): Factory function to create new resources when pool is not at capacityonbind (function): Called when a resource is taken from the poolonunbind (function): Called when a resource is returned to the pool... (any): Additional arguments passed to onbind callbackReturns:
pool: Pool instanceExample:
local pool = require "fan.pool"
-- Simple pool with factory function
local db_pool = pool.new({
onnew = function(pool_instance)
return connect_to_database()
end
})
Get a resource from the pool. If no resources are available and the pool is at capacity, this will yield until a resource becomes available.
Returns:
onbind if provided)Example:
local connection = db_pool:pop()
-- Use connection...
db_pool:push(connection)
Return a resource to the pool. This will automatically resume any waiting coroutines if there are queued requests.
Parameters:
resource (any): The resource to return to the poolExample:
local connection = db_pool:pop()
-- ... use connection ...
db_pool:push(connection) -- Return to pool
Execute a function with a resource from the pool, automatically handling resource cleanup even if the function throws an error.
Parameters:
func (function): Function to execute, receives the resource as first parameter... (any): Additional arguments passed to the functionReturns:
Example:
local result = db_pool:safe(function(connection, query)
return connection:execute(query)
end, "SELECT * FROM users")
The pool size is controlled by the config.pool_size setting, which defaults to 10 if not specified.
local pool = require "fan.pool"
local mariadb = require "fan.mariadb"
local db_pool = pool.new({
onnew = function(pool_instance)
return mariadb.connect({
host = "localhost",
user = "app",
password = "secret",
database = "myapp"
})
end,
onbind = function(connection, bind_args)
-- Reset connection state if needed
connection:execute("SET autocommit=1")
return connection
end,
onunbind = function(connection)
-- Clean up connection state
connection:execute("ROLLBACK") -- Ensure no pending transactions
return connection
end
})
-- Usage with automatic cleanup
db_pool:safe(function(conn)
local result = conn:execute("SELECT COUNT(*) FROM users")
print("User count:", result[1][1])
end)
local pool = require "fan.pool"
local http = require "fan.http"
local http_pool = pool.new({
onnew = function(pool_instance)
return {
session = http.session(),
requests_made = 0
}
end,
onbind = function(client_info)
client_info.requests_made = client_info.requests_made + 1
return client_info.session
end,
onunbind = function(session, client_info)
-- Recycle connection if too many requests made
if client_info.requests_made > 100 then
client_info.session:close()
return nil -- Remove from pool
end
return client_info
end
})
-- Make HTTP requests through pool
http_pool:safe(function(session)
local response = session:get("https://api.example.com/data")
return response.body
end)
local pool = require "fan.pool"
local worker = require "fan.worker"
local worker_pool = pool.new({
onnew = function(pool_instance)
return worker.new({
script = "worker_script.lua"
})
end,
onunbind = function(worker_instance)
-- Check if worker is still healthy
if not worker_instance:is_alive() then
return nil -- Remove dead worker from pool
end
return worker_instance
end
})
-- Distribute work across worker pool
for i = 1, 100 do
worker_pool:safe(function(w)
return w:call("process_data", {id = i})
end)
end
safe() method ensures resources are always returned to poolconfig.pool_size but each pool instance maintains its own resourcessafe() for exception safety when possibleonbind/onunbind lightweight as they’re called frequentlyonunbind by returning nil to remove bad resources