Hi,
We have puma configured with 4 workers and min/max threads set to 5. We currently create a rom configuration and cache it in a variable.
module MyPersistance
extend Dry::Configurable
...
def self.configuration
@configuration ||= ROM::Configuration.new(gateways) do |config|
...
config.auto_registration(registration_path, ...)
...
And do the same for a container.
def self.container
@container ||= ROM.container(configuration)
Then when instantiating our repositories we pass the container to #new.
MyRepository.new(MyPersistance.container, ...)
This is obviously not thread safe and is causing lots of errors not seen using webrick.
If I remove the caching I get the error “Mysql2::Error: Too many connections”
I have read this post and related issue:
rom-gateways-and-sequel-pools
I need some more concrete guidance. What is your recommendation on structuring this correctly to work with puma?
My configuration looks something like this
# The default options for ROM::Gateway
def connection_options
{
connect_timeout: 2,
max_connections: @slice.settings.max_threads,
extensions: %i[connection_validator error_sql pg_array pg_json ksuid]
}
end
# @api private
def to_gateway
ROM::Gateway.setup(:sql, to_uri, connection_options)
end
# @api private
def to_config
ROM::Configuration.new(default: to_gateway).tap do |config|
config.gateways.each do |(_, gw)|
gw.connection.pool.connection_validation_timeout = -1
end
config.plugin(:sql, relations: :auto_restrictions)
end
end
Where @slice.settings.max_threads
comes from and env var, and is set in the puma config:
max_threads_count = ENV.fetch("HANAMI_MAX_THREADS", 5)
min_threads_count = ENV.fetch("HANAMI_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
You might need up to 20 connections for 4 workers and 5 threads. If your Configuration connection is over 20, try setting it to be more than 20.
Another possible issue might be that you haven’t properly released the database connection. If this is the case, you might notice many unhandled exceptions.