84 lines
2.1 KiB
Python
84 lines
2.1 KiB
Python
import asyncio
|
|
import atexit
|
|
import os
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
from urllib.parse import urlparse
|
|
import uvicorn
|
|
|
|
# 将项目根目录添加到 python 路径
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
|
|
|
|
_SIDECAR_PROCESS: subprocess.Popen | None = None
|
|
|
|
|
|
def _parse_sidecar_target() -> tuple[str, int]:
|
|
sidecar_url = os.getenv("COPILOT_SIDECAR_URL", "http://127.0.0.1:8787").strip()
|
|
parsed = urlparse(sidecar_url)
|
|
host = parsed.hostname or "127.0.0.1"
|
|
port = parsed.port or 8787
|
|
return host, port
|
|
|
|
|
|
def _stop_sidecar() -> None:
|
|
global _SIDECAR_PROCESS
|
|
proc = _SIDECAR_PROCESS
|
|
if proc is None:
|
|
return
|
|
if proc.poll() is None:
|
|
proc.terminate()
|
|
try:
|
|
proc.wait(timeout=5)
|
|
except subprocess.TimeoutExpired:
|
|
proc.kill()
|
|
proc.wait(timeout=3)
|
|
_SIDECAR_PROCESS = None
|
|
|
|
|
|
def _start_sidecar_if_needed() -> None:
|
|
global _SIDECAR_PROCESS
|
|
sidecar_dir = os.path.abspath(
|
|
os.path.join(os.path.dirname(__file__), "..", "copilot-sidecar")
|
|
)
|
|
|
|
host, port = _parse_sidecar_target()
|
|
cmd = [
|
|
sys.executable,
|
|
"-m",
|
|
"uvicorn",
|
|
"server:app",
|
|
"--host",
|
|
host,
|
|
"--port",
|
|
str(port),
|
|
"--log-level",
|
|
os.getenv("COPILOT_SIDECAR_LOG_LEVEL", "warning"),
|
|
]
|
|
_SIDECAR_PROCESS = subprocess.Popen(cmd, cwd=sidecar_dir)
|
|
print(f"[run_server] sidecar started at {host}:{port}.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Windows 设置事件循环策略
|
|
if sys.platform == "win32":
|
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
|
|
atexit.register(_stop_sidecar)
|
|
signal.signal(signal.SIGTERM, lambda *_: _stop_sidecar())
|
|
signal.signal(signal.SIGINT, lambda *_: _stop_sidecar())
|
|
|
|
_start_sidecar_if_needed()
|
|
try:
|
|
# 用 uvicorn.run 支持 workers 参数
|
|
uvicorn.run(
|
|
"app.main:app",
|
|
host="0.0.0.0",
|
|
port=8000,
|
|
# workers=2, # 这里可以设置多进程
|
|
loop="asyncio",
|
|
)
|
|
finally:
|
|
_stop_sidecar()
|