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

feat: 支持fork #221

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions pywss/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding: utf-8
import os
import re
import sys
import json
import time
import gzip
Expand Down Expand Up @@ -757,6 +758,25 @@ def watchdog(self, interval: float = float(os.environ.get("PYWSS_WATCHDOG_INTERV
time.sleep(interval)
log.warning("exit")

def fork_processes(self, num_processes: int):
if sys.platform == "win32":
raise Exception("fork not available on windows")
pids = {}
num_processes = num_processes if num_processes > 0 else os.cpu_count()
for i in range(num_processes):
pid = os.fork()
if pid == 0: # child process
return pid
else:
pids[pid] = i
# main process
while pids:
pid, status = os.wait()
if pid not in pids:
continue
pids.pop(pid)
return None

def run(
self,
host: str = "0.0.0.0",
Expand All @@ -767,6 +787,8 @@ def run(
thread_pool_size: int = int(os.environ.get("PYWSS_THREAD_POOL_SIZE", min(30, (os.cpu_count() or 1) * 5))),
thread_pool_idle_time: int = int(os.environ.get("PYWSS_THREAD_POOL_IDLE_TIME", 300)),
watch: bool = os.environ.get("PYWSS_WATCHDOG_ENABLE", "false").lower() == "true",
fork: bool = False,
num_processes: int = 0,
) -> None:
# build app with [route:handler]
self.build()
Expand All @@ -775,8 +797,15 @@ def run(
# rigister signal closing
for sig in (signal.SIGTERM, signal.SIGINT, signal.SIGILL):
signal.signal(sig, lambda *args: self.close())
# use os.fork
if fork:
pid = self.fork_processes(num_processes)
if pid is None:
return
# socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
if fork: # child
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind((host, port))
sock.listen(select_size)
# queue of threading pool
Expand Down
Loading