Skip to content
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

Allow setting number of processes/threads through DRAMATIQ_NPROCS, DRAMATIQ_NTHREADS. #186

Merged
merged 2 commits into from
Feb 24, 2025

Conversation

m000
Copy link
Contributor

@m000 m000 commented Feb 4, 2025

Use case: I use rundramatiq to start dramatiq in a docker-compose environment. However, since all my CPUs are detected by docker, I get an excessive number of workers which are slow to restart, but otherwise mostly idling.

With this PR, it is allowed to instruct rundramatiq to use a specific number of processes, threads per process via the DRAMATIQ_NPROCS, DRAMATIQ_NTHREADS environment variables. These variables can be set e.g. in your .env file, where docker-compose will pick them up and pass them to rundramatiq.

This would also be useful in general when using rundramatiq in any containerized environment, as it is usually preferred to configure software through the environment, rather than modifying the actual command line used by the container.

Copy link
Collaborator

@andrewgy8 andrewgy8 left a comment

Choose a reason for hiding this comment

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

Looks good overall, however there a couple of comments that will need addressing. Thanks!

if default is None:
raise
msgf = "Invalid value for %s: %r. Reverting to default."
logging.warning(msgf, varname, envstr)
Copy link
Collaborator

Choose a reason for hiding this comment

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

suggestion: i wonder if we should reraise the ValueError here with the warning message. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While I wouldn't object to (essentially) not handle ValueError, as a user I would expect a warning and some best-effort fallback instead of a hard failure.

This is common behaviour when it comes to values set through environment variables. E.g. VIM=/does/not/exist vim script.py will have vim complain about the non-existing directory, but the editor will open. Or with TERM=wtf ls, ls will complain but still run and assume a dumb terminal.

Comment on lines +17 to +21
# Number of processes to use. Default: one per CPU.
NPROCS = getenv_int("DRAMATIQ_NPROCS", default=multiprocessing.cpu_count)

# Number of threads per process to use. Default: 8.
NTHREADS = getenv_int("DRAMATIQ_NTHREADS", 8)
Copy link
Collaborator

Choose a reason for hiding this comment

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

suggestion: Another way to do this is to use a setting, and then allow the user to set the setting themselves, rather than django-dramatiq grabbing it from the environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an intentional choice. I have considered adding a setting, but I concluded that an environment variable would be the appropriate solution here, since the value that should be used depends on the deployment environment.

Adding a setting would be less convenient because application setting files are typically versioned (in scm) and reused across different deployment environments. A setting which is dictated by the deployment environment would create complexities for the users.

E.g. I run the same developer setup as everyone else in my team, but I happen to have less cores on my computer. Putting e.g. DRAMATIQ_NPROCS in django settings, means that we will have to now add custom code to properly set the value for everyone. And that custom code would probably involve checking some environment variable. Having django-dramatiq handle this out of the box is

Also, in containerized environments (k8s, docker-compose etc.) the preferred way of configuring resource-related settings is through environment variables, as you don't want to update/fork your application settings file for every clone of your setup.

One could of course add settings as an additional link in the fallback chain: cli argument -> environment -> application setting -> auto-guess default value. But this can always be done at a later time, in a separate PR. At this point, IMHO, it would only add extra complexity to the codebase without offering any additional convenience.

I hope this explains this design choice.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for the explanation.

One could of course add settings as an additional link in the fallback chain: cli argument -> environment -> application setting -> auto-guess default value.

Lets get this in a see if the users are missing it.

@m000
Copy link
Contributor Author

m000 commented Feb 21, 2025

Looks good overall, however there a couple of comments that will need addressing. Thanks!

Thanks for the feedback @andrewgy8. Please see comments above.

python manage.py rundramatiq
```

By default, `rundramatiq` will adjust the number of processes/threads used
Copy link
Collaborator

Choose a reason for hiding this comment

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

thought: We really should get a separate documentation page...

@andrewgy8
Copy link
Collaborator

Thanks a lot for the contribution!

@andrewgy8 andrewgy8 merged commit 08be4f6 into Bogdanp:master Feb 24, 2025
14 checks passed
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.

2 participants