-
Notifications
You must be signed in to change notification settings - Fork 138
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
Set RAILS_MAX_THREADS
as the default number of worker threads
#449
Set RAILS_MAX_THREADS
as the default number of worker threads
#449
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call! Thank you so much @genya0407! 🙏
Ah, no, wait! That would cause an error, very probably, because solid queue processes need more DB connections than just the number of threads. They run another thread for the heartbeat, and the polling happens in the main thread. |
Could this be why I am getting this error message:
Because I only have 30 connections available to my MySQL database? |
@rosa
Let me sort out my understanding of Rails/SolidQueue's connection pools.
Each primary / replica / queue connection pool holds Therefore, the following conditions must be satisfied:
To satisfy the latter condition, we might need to instruct users to set production:
primary: &primary_production
<<: *default
database: app_production
username: app
password: <%= ENV["APP_DATABASE_PASSWORD"] %>
queue:
<<: *primary_production
# 1 connection for each worker thread, 1 connection for the main thread
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } + 1 %>
database: app_production_queue
migrations_paths: db/queue_migrate Or we can decrease the number of worker threads like: workers:
- queues: "*"
threads: <%= ENV.fetch("RAILS_MAX_THREADS", 3) - 1 %> # 1 connection is consumed for polling
processes: <%%= ENV.fetch("JOB_CONCURRENCY", 1) %>
polling_interval: 0.1 I believe the former option is better. |
@epugh Increasing the |
Thanks @genya0407! It'd be
with +2 accounting for the polling in the main thread and the heartbeat thread. The first option you propose (with +2 instead of +1) sounds good, but it'd require changes in Rails to generate the default I'm also thinking a bit more about this, and perhaps it's not desirable to use the same value for Puma threads as for Solid Queue threads since the nature of work there is very different. The fact that the DB pool is set to that size doesn't mean Solid Queue needs to max out the number of connections 🤔 |
@rosa
workers:
- queues: "*"
# 1 connection is consumed for polling, 1 connection is consumed for heartbeat
threads: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } - 2 %>
processes: <%%= ENV.fetch("JOB_CONCURRENCY", 1) %>
polling_interval: 0.1
We might consider offering more modest default threads: <%= [ENV.fetch("RAILS_MAX_THREADS") { 5 } - 2, 3].min %> With this, we will be able to avoid stacking in obtaining connections and launching too many worker threads. |
In this case, you need to handle the case where someone has set
I don't think this is a guarantee or something that necessarily applies to Solid Queue. Rails guarantees that the web server won't run out of DB connections with that setting because it uses that setting for the web server, but it wasn't something set for Solid Queue or even relevant 🤔 I think it'd be simpler to just keep the default of |
I agree. Then I'm closing this PR.
It might be better to document this in README.md as a hint for choosing optimal configuration. If so, I will open a separate PR later. |
@genya0407 agree! The only documentation we have on |
The number of worker threads in solid_queue must be less than or equal to the size of the database connection pool.
Otherwise, the worker threads might get stuck while trying to obtain a connection from the pool.
Rails sets
RAILS_MAX_THREADS
as the default size of the database connection pool:Therefore, we should set
RAILS_MAX_THREADS
as the default number of threads for solid_queue.If the
RAILS_MAX_THREADS
environment variable is not set,3
will be a good default value becausepuma.rb
also uses3
as the default number of worker threads.