Addon起動の環境問題
This commit is contained in:
parent
a2131a962b
commit
f2665a49dd
|
|
@ -24,6 +24,8 @@ class InferenceClient:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.server_process: Optional[subprocess.Popen] = None
|
self.server_process: Optional[subprocess.Popen] = None
|
||||||
self._server_lock = threading.Lock()
|
self._server_lock = threading.Lock()
|
||||||
|
self.log_file = None
|
||||||
|
self.log_file_path = None
|
||||||
|
|
||||||
def start_server(self):
|
def start_server(self):
|
||||||
"""Start the inference server process."""
|
"""Start the inference server process."""
|
||||||
|
|
@ -52,28 +54,54 @@ class InferenceClient:
|
||||||
server_env[key] = value
|
server_env[key] = value
|
||||||
print(f"[FaceMask] Loaded environment from: {env_file}")
|
print(f"[FaceMask] Loaded environment from: {env_file}")
|
||||||
|
|
||||||
# Ensure PYTHONPATH includes project root
|
# Clean PYTHONPATH to avoid conflicts with Nix Python packages
|
||||||
pythonpath = server_env.get('PYTHONPATH', '')
|
# Only include project root to allow local imports
|
||||||
if pythonpath:
|
server_env['PYTHONPATH'] = root_dir
|
||||||
server_env['PYTHONPATH'] = f"{root_dir}:{pythonpath}"
|
|
||||||
else:
|
# Remove Python-related environment variables that might cause conflicts
|
||||||
server_env['PYTHONPATH'] = root_dir
|
# These can cause venv to import packages from Nix instead of venv
|
||||||
|
env_vars_to_remove = [
|
||||||
|
'PYTHONUNBUFFERED',
|
||||||
|
'__PYVENV_LAUNCHER__', # macOS venv variable
|
||||||
|
'VIRTUAL_ENV', # Will be set by venv's Python automatically
|
||||||
|
]
|
||||||
|
for var in env_vars_to_remove:
|
||||||
|
server_env.pop(var, None)
|
||||||
|
|
||||||
# If there's a venv in the project, add it to PATH
|
# If there's a venv in the project, add it to PATH
|
||||||
venv_bin = os.path.join(root_dir, ".venv", "bin")
|
venv_bin = os.path.join(root_dir, ".venv", "bin")
|
||||||
if os.path.isdir(venv_bin):
|
if os.path.isdir(venv_bin):
|
||||||
|
# Build a clean PATH with venv first, then essential system paths
|
||||||
|
# Filter out any Nix Python-specific paths to avoid version conflicts
|
||||||
current_path = server_env.get('PATH', '')
|
current_path = server_env.get('PATH', '')
|
||||||
server_env['PATH'] = f"{venv_bin}:{current_path}"
|
path_entries = current_path.split(':')
|
||||||
|
|
||||||
|
# Filter out Nix Python 3.11 paths
|
||||||
|
filtered_paths = [
|
||||||
|
p for p in path_entries
|
||||||
|
if not ('/python3.11/' in p.lower() or '/python3-3.11' in p.lower())
|
||||||
|
]
|
||||||
|
|
||||||
|
# Reconstruct PATH with venv first
|
||||||
|
clean_path = ':'.join([venv_bin] + filtered_paths)
|
||||||
|
server_env['PATH'] = clean_path
|
||||||
print(f"[FaceMask] Using venv from: {venv_bin}")
|
print(f"[FaceMask] Using venv from: {venv_bin}")
|
||||||
|
|
||||||
|
# Prepare log file for server output
|
||||||
|
import tempfile
|
||||||
|
log_dir = tempfile.gettempdir()
|
||||||
|
self.log_file_path = os.path.join(log_dir, "facemask_server.log")
|
||||||
|
self.log_file = open(self.log_file_path, 'w', buffering=1) # Line buffered
|
||||||
|
print(f"[FaceMask] Server log: {self.log_file_path}")
|
||||||
|
|
||||||
# Start process with 'python' command (will use venv if PATH is set correctly)
|
# Start process with 'python' command (will use venv if PATH is set correctly)
|
||||||
self.server_process = subprocess.Popen(
|
self.server_process = subprocess.Popen(
|
||||||
["python", server_script],
|
["python", "-u", server_script], # -u for unbuffered output
|
||||||
cwd=root_dir,
|
cwd=root_dir,
|
||||||
text=True,
|
text=True,
|
||||||
env=server_env,
|
env=server_env,
|
||||||
stdout=subprocess.PIPE, # Capture stdout
|
stdout=self.log_file, # Write to log file
|
||||||
stderr=subprocess.PIPE, # Capture stderr
|
stderr=subprocess.STDOUT, # Merge stderr into stdout
|
||||||
preexec_fn=os.setsid, # Create new process group
|
preexec_fn=os.setsid, # Create new process group
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -85,22 +113,23 @@ class InferenceClient:
|
||||||
|
|
||||||
# Check if process died
|
# Check if process died
|
||||||
if self.server_process.poll() is not None:
|
if self.server_process.poll() is not None:
|
||||||
# Capture and display error output
|
# Read error output from log file
|
||||||
try:
|
|
||||||
stdout, stderr = self.server_process.communicate(timeout=1)
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
stdout, stderr = "", ""
|
|
||||||
|
|
||||||
error_msg = f"Server failed to start (exit code: {self.server_process.returncode})"
|
error_msg = f"Server failed to start (exit code: {self.server_process.returncode})"
|
||||||
print(f"[FaceMask] ERROR: {error_msg}")
|
print(f"[FaceMask] ERROR: {error_msg}")
|
||||||
|
|
||||||
if stdout and stdout.strip():
|
try:
|
||||||
print("[FaceMask] Server stdout:")
|
if self.log_file:
|
||||||
print(stdout.strip())
|
self.log_file.close()
|
||||||
|
with open(self.log_file_path, 'r') as f:
|
||||||
if stderr and stderr.strip():
|
log_content = f.read()
|
||||||
print("[FaceMask] Server stderr:")
|
if log_content.strip():
|
||||||
print(stderr.strip())
|
print("[FaceMask] Server log:")
|
||||||
|
# Show last 50 lines
|
||||||
|
lines = log_content.strip().split('\n')
|
||||||
|
for line in lines[-50:]:
|
||||||
|
print(line)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[FaceMask] Could not read log file: {e}")
|
||||||
|
|
||||||
self.server_process = None
|
self.server_process = None
|
||||||
raise RuntimeError(error_msg)
|
raise RuntimeError(error_msg)
|
||||||
|
|
@ -108,19 +137,21 @@ class InferenceClient:
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
# If we get here, startup timed out
|
# If we get here, startup timed out
|
||||||
# Try to capture any partial output
|
print("[FaceMask] Server startup timed out")
|
||||||
if self.server_process:
|
|
||||||
try:
|
# Try to read partial log
|
||||||
# Non-blocking read with short timeout
|
try:
|
||||||
stdout, stderr = self.server_process.communicate(timeout=0.1)
|
if self.log_file:
|
||||||
if stdout and stdout.strip():
|
self.log_file.close()
|
||||||
print("[FaceMask] Server stdout (partial):")
|
with open(self.log_file_path, 'r') as f:
|
||||||
print(stdout.strip())
|
log_content = f.read()
|
||||||
if stderr and stderr.strip():
|
if log_content.strip():
|
||||||
print("[FaceMask] Server stderr (partial):")
|
print("[FaceMask] Server log (partial):")
|
||||||
print(stderr.strip())
|
lines = log_content.strip().split('\n')
|
||||||
except subprocess.TimeoutExpired:
|
for line in lines[-30:]:
|
||||||
pass # Process still running but not responding
|
print(line)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
raise RuntimeError("Server startup timed out")
|
raise RuntimeError("Server startup timed out")
|
||||||
|
|
||||||
|
|
@ -137,6 +168,14 @@ class InferenceClient:
|
||||||
finally:
|
finally:
|
||||||
self.server_process = None
|
self.server_process = None
|
||||||
|
|
||||||
|
# Close log file
|
||||||
|
if self.log_file:
|
||||||
|
try:
|
||||||
|
self.log_file.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self.log_file = None
|
||||||
|
|
||||||
def is_server_running(self) -> bool:
|
def is_server_running(self) -> bool:
|
||||||
"""Check if server is responding."""
|
"""Check if server is responding."""
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user