Called when the child process starts. * config - The Uvicorn configuration instance. * target - A callable that accepts a list of sockets. In practice this will be the `Server.run()` method. * sockets - A list of sockets to pass to the server. Sockets are bound once
(
config: Config,
target: Callable[..., None],
sockets: list[socket],
stdin_fileno: int | None,
)
| 52 | |
| 53 | |
| 54 | def subprocess_started( |
| 55 | config: Config, |
| 56 | target: Callable[..., None], |
| 57 | sockets: list[socket], |
| 58 | stdin_fileno: int | None, |
| 59 | ) -> None: |
| 60 | """ |
| 61 | Called when the child process starts. |
| 62 | |
| 63 | * config - The Uvicorn configuration instance. |
| 64 | * target - A callable that accepts a list of sockets. In practice this will |
| 65 | be the `Server.run()` method. |
| 66 | * sockets - A list of sockets to pass to the server. Sockets are bound once |
| 67 | by the parent process, and then passed to the child processes. |
| 68 | * stdin_fileno - The file number of sys.stdin, so that it can be reattached |
| 69 | to the child process. |
| 70 | """ |
| 71 | # Re-open stdin. |
| 72 | if stdin_fileno is not None: |
| 73 | sys.stdin = os.fdopen(stdin_fileno) # pragma: full coverage |
| 74 | |
| 75 | # Logging needs to be setup again for each child. |
| 76 | config.configure_logging() |
| 77 | |
| 78 | try: |
| 79 | # Now we can call into `Server.run(sockets=sockets)` |
| 80 | target(sockets=sockets) |
| 81 | except KeyboardInterrupt: # pragma: no cover |
| 82 | # suppress the exception to avoid a traceback from subprocess.Popen |
| 83 | # the parent already expects us to end, so no vital information is lost |
| 84 | pass |