ranchimallflo-api/py3.7/lib/python3.7/site-packages/hypercorn/run.py

81 lines
2.2 KiB
Python

import platform
import random
import signal
import time
from multiprocessing import Event, Process
from typing import Any
from .config import Config
from .typing import WorkerFunc
from .utils import write_pid_file
def run(config: Config) -> None:
if config.pid_path is not None:
write_pid_file(config.pid_path)
worker_func: WorkerFunc
if config.worker_class == "asyncio":
from .asyncio.run import asyncio_worker
worker_func = asyncio_worker
elif config.worker_class == "uvloop":
from .asyncio.run import uvloop_worker
worker_func = uvloop_worker
elif config.worker_class == "trio":
from .trio.run import trio_worker
worker_func = trio_worker
else:
raise ValueError(f"No worker of class {config.worker_class} exists")
if config.workers == 1:
worker_func(config)
else:
run_multiple(config, worker_func)
def run_multiple(config: Config, worker_func: WorkerFunc) -> None:
if config.use_reloader:
raise RuntimeError("Reloader can only be used with a single worker")
sockets = config.create_sockets()
processes = []
# Ignore SIGINT before creating the processes, so that they
# inherit the signal handling. This means that the shutdown
# function controls the shutdown.
signal.signal(signal.SIGINT, signal.SIG_IGN)
shutdown_event = Event()
for _ in range(config.workers):
process = Process(
target=worker_func,
kwargs={"config": config, "shutdown_event": shutdown_event, "sockets": sockets},
)
process.daemon = True
process.start()
processes.append(process)
if platform.system() == "Windows":
time.sleep(0.1 * random.random())
def shutdown(*args: Any) -> None:
shutdown_event.set()
for signal_name in {"SIGINT", "SIGTERM", "SIGBREAK"}:
if hasattr(signal, signal_name):
signal.signal(getattr(signal, signal_name), shutdown)
for process in processes:
process.join()
for process in processes:
process.terminate()
for sock in sockets.secure_sockets:
sock.close()
for sock in sockets.insecure_sockets:
sock.close()