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
New multiprocess manager #2183
base: master
Are you sure you want to change the base?
New multiprocess manager #2183
Conversation
pyproject.toml
Outdated
@@ -100,7 +100,7 @@ omit = [ | |||
|
|||
[tool.coverage.report] | |||
precision = 2 | |||
fail_under = 98.35 | |||
fail_under = 96.82 |
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.
I'm not willing to introduce this feature without testing it.
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.
Yes, I just want to see your attitude towards this PR before adding the test. Because I remember you have implemented something similar before.
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.
Ah, then let me review and get back to you.
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.
Checklist
- Increase coverage for the new multiprocess manager to 100% (if tests are slow, run on a separate job in the CI, and only if the
multiprocess.py
is changed). - Docstrings.
- Documentation (I can help here).
- Answer the question: how this should interact with
--reload
? - Move
UvicornWorker
out from Uvicorn's source code (I'll do it).
@abersheeran I'm fully available to move this forward. 👍 |
…process-manager
Ok. 👍 We can move forward with the checklist above 🙏 |
uvicorn/supervisors/multiprocess.py
Outdated
process.terminate() | ||
process.join() | ||
del self.processes[idx] | ||
process = Process(self.config, self.target, self.sockets) | ||
process.start() |
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.
Are you confirmed this is the behavior that you want? Shutdown first, then start the new processes with a potential gap in coverage? This was the initial pattern we went for with Sanic, but we received requests and ran into use cases where it was not desired and therefore offered it as configurable: https://github.com/sanic-org/sanic/blob/main/sanic/worker/process.py#L109
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.
What problems might this gap cause?
process = Process(self.config, self.target, self.sockets) | ||
process.start() | ||
self.processes.append(process) |
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.
This pattern of Process
instantiation, start
, and append
is scattered in several locations. This will IMO become an issue over time as features are built on top of this. I'd suggest centralizing that somehow in a nicer pattern that allows more flexibility.
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.
Excessive abstraction can cause more problems. I don't think a unified approach is needed until many of the new features you talk about are added. At least in my opinion, multi-process managers only have these functions at most (see gunicorn)
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.
I see what the PR is doing, but I somewhat fail to understand the why and the goals. Is the pinging the ultimate feature add here?
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.
I think we need to change the logs to print the PID, otherwise it gets confusing:
❯ uvicorn main:app --workers 2
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started parent process [9954]
INFO: Started child process [9956]
INFO: Started child process [9957]
INFO: Started server process [9956]
INFO: Started server process [9957]
INFO: Waiting for application startup.
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Application startup complete.
@@ -101,7 +101,7 @@ omit = [ | |||
|
|||
[tool.coverage.report] | |||
precision = 2 | |||
fail_under = 98.35 | |||
fail_under = 98.13 |
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.
I don't want to decrease this, can we add pragmas where needed?
Also, if I press |
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Can you try the latest commit version? This should solve the problem. |
Summary
About #2164.
The multiprocess manager introduced by this PR includes process keep-alive and process hung detection. It also imitates gunicorn and uses hup, ttin, and ttou signals to control child processes.
Checklist