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

New multiprocess manager #2183

Open
wants to merge 58 commits into
base: master
Choose a base branch
from

Conversation

abersheeran
Copy link
Member

@abersheeran abersheeran commented Dec 15, 2023

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

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

pyproject.toml Outdated
@@ -100,7 +100,7 @@ omit = [

[tool.coverage.report]
precision = 2
fail_under = 98.35
fail_under = 96.82
Copy link
Sponsor Member

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.

Copy link
Member Author

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.

Copy link
Sponsor Member

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.

@Kludex Kludex added the waiting author Waiting for author's reply label Jan 20, 2024
Copy link
Sponsor Member

@Kludex Kludex left a 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).

uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Show resolved Hide resolved
@Kludex
Copy link
Sponsor Member

Kludex commented Mar 2, 2024

@abersheeran I'm fully available to move this forward. 👍

@Kludex
Copy link
Sponsor Member

Kludex commented Mar 3, 2024

Pinging @ahopkins to review the initial steps since he offered helped on #2164. 🙏

@Kludex
Copy link
Sponsor Member

Kludex commented Mar 4, 2024

Ok. 👍

We can move forward with the checklist above 🙏

Comment on lines 146 to 150
process.terminate()
process.join()
del self.processes[idx]
process = Process(self.config, self.target, self.sockets)
process.start()
Copy link
Member

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

Copy link
Member Author

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?

Comment on lines +221 to +223
process = Process(self.config, self.target, self.sockets)
process.start()
self.processes.append(process)
Copy link
Member

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.

Copy link
Member Author

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)

Copy link
Member

@ahopkins ahopkins left a 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?

@ahopkins ahopkins self-requested a review March 4, 2024 09:21
@Kludex Kludex added the hold Don't merge yet label Mar 4, 2024
@abersheeran abersheeran requested a review from Kludex April 5, 2024 14:56
@abersheeran abersheeran removed waiting author Waiting for author's reply hold Don't merge yet labels Apr 5, 2024
Copy link
Sponsor Member

@Kludex Kludex left a 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.

docs/deployment.md Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
uvicorn/supervisors/multiprocess.py Outdated Show resolved Hide resolved
@@ -101,7 +101,7 @@ omit = [

[tool.coverage.report]
precision = 2
fail_under = 98.35
fail_under = 98.13
Copy link
Sponsor Member

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?

@Kludex
Copy link
Sponsor Member

Kludex commented Apr 13, 2024

Also, if I press CTRL + C on uvicorn main:app --workers 2, it doesn't work as expected.

@Kludex Kludex added the waiting author Waiting for author's reply label Apr 13, 2024
abersheeran and others added 9 commits April 14, 2024 16:14
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>
@abersheeran
Copy link
Member Author

abersheeran commented Apr 14, 2024

Also, if I press CTRL + C on uvicorn main:app --workers 2, it doesn't work as expected.

Can you try the latest commit version? This should solve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting author Waiting for author's reply
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants