fix:优化wsl环境下的边缘设备执行逻辑

This commit is contained in:
Daniel
2026-04-07 02:06:43 +08:00
parent afec0980d4
commit 6b9b9d60b5
7 changed files with 439 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ import asyncio
import json
import os
from pathlib import Path
import subprocess
import sys
import time
from urllib.parse import urlparse
@@ -13,6 +14,12 @@ DISPATCH_WS_URL = os.getenv("DISPATCH_WS_URL", "ws://127.0.0.1:8020/ws/edge/edge
WORKER_BASE_URL = os.getenv("WORKER_BASE_URL", "http://127.0.0.1:8000")
POLL_INTERVAL = float(os.getenv("EDGE_POLL_INTERVAL_SEC", "1.0"))
DISPATCH_HTTP_BASE = os.getenv("DISPATCH_HTTP_BASE", "")
ALLOW_REMOTE_UPDATE = os.getenv("EDGE_ALLOW_REMOTE_UPDATE", "true").lower() in {"1", "true", "yes", "on"}
ALLOW_REMOTE_RESTART = os.getenv("EDGE_ALLOW_REMOTE_RESTART", "true").lower() in {"1", "true", "yes", "on"}
SCRIPT_DIR = Path(__file__).resolve().parent
ROOT_DIR = SCRIPT_DIR.parent
RESTART_SCRIPT = ROOT_DIR / "scripts" / "restart_edge_device_local.sh"
if len(sys.argv) > 1:
DISPATCH_WS_URL = sys.argv[1]
@@ -41,6 +48,18 @@ def worker_get(path: str):
return r.json()
def run_shell(command: str, timeout_sec: int = 1200) -> tuple[int, str, str]:
proc = subprocess.run(
command,
cwd=str(ROOT_DIR),
shell=True,
text=True,
capture_output=True,
timeout=timeout_sec,
)
return proc.returncode, proc.stdout.strip(), proc.stderr.strip()
def upload_artifacts(dispatch_id: str, task_id: str, result: dict) -> dict:
candidate_fields = ["video_path", "first_frame_path", "metadata_path", "log_path"]
existing_paths = []
@@ -78,6 +97,12 @@ def upload_artifacts(dispatch_id: str, task_id: str, result: dict) -> dict:
fh.close()
def _short_text(text: str, limit: int = 1500) -> str:
if len(text) <= limit:
return text
return text[:limit] + "...(truncated)"
async def handle_generate(ws, data: dict):
dispatch_id = data["dispatch_id"]
req = data["request"]
@@ -114,13 +139,126 @@ async def handle_generate(ws, data: dict):
result_payload["artifact_urls"] = artifact_urls
else:
result_payload["error"] = result.get("error")
await ws.send(
json.dumps(result_payload, ensure_ascii=False)
)
await ws.send(json.dumps(result_payload, ensure_ascii=False))
return
await asyncio.sleep(POLL_INTERVAL)
async def handle_update_code(ws, data: dict):
dispatch_id = data.get("dispatch_id", "")
if not ALLOW_REMOTE_UPDATE:
await ws.send(
json.dumps(
{
"event": "command_result",
"dispatch_id": dispatch_id,
"command": "update_code",
"status": "FAILED",
"error": "EDGE_ALLOW_REMOTE_UPDATE=false",
},
ensure_ascii=False,
)
)
return
branch = data.get("branch", "master")
git_command = data.get("command") or f"git fetch --all && git checkout {branch} && git pull --ff-only origin {branch}"
await ws.send(
json.dumps(
{"event": "command_status", "dispatch_id": dispatch_id, "command": "update_code", "status": "RUNNING"},
ensure_ascii=False,
)
)
code, out, err = await asyncio.to_thread(run_shell, git_command, 1800)
payload = {
"event": "command_result",
"dispatch_id": dispatch_id,
"command": "update_code",
"status": "SUCCEEDED" if code == 0 else "FAILED",
"exit_code": code,
"stdout": _short_text(out),
"stderr": _short_text(err),
}
await ws.send(json.dumps(payload, ensure_ascii=False))
async def handle_restart_service(ws, data: dict):
dispatch_id = data.get("dispatch_id", "")
if not ALLOW_REMOTE_RESTART:
await ws.send(
json.dumps(
{
"event": "command_result",
"dispatch_id": dispatch_id,
"command": "restart_service",
"status": "FAILED",
"error": "EDGE_ALLOW_REMOTE_RESTART=false",
},
ensure_ascii=False,
)
)
return
if not RESTART_SCRIPT.exists():
await ws.send(
json.dumps(
{
"event": "command_result",
"dispatch_id": dispatch_id,
"command": "restart_service",
"status": "FAILED",
"error": f"restart script missing: {RESTART_SCRIPT}",
},
ensure_ascii=False,
)
)
return
await ws.send(
json.dumps(
{"event": "command_status", "dispatch_id": dispatch_id, "command": "restart_service", "status": "RUNNING"},
ensure_ascii=False,
)
)
await ws.send(
json.dumps(
{
"event": "command_result",
"dispatch_id": dispatch_id,
"command": "restart_service",
"status": "SUCCEEDED",
"message": "restart script launched",
},
ensure_ascii=False,
)
)
subprocess.Popen(
["bash", str(RESTART_SCRIPT)],
cwd=str(ROOT_DIR),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True,
)
raise SystemExit(0)
async def handle_ping(ws, data: dict):
await ws.send(
json.dumps(
{
"event": "pong",
"dispatch_id": data.get("dispatch_id", ""),
"status": "ok",
"worker_base_url": WORKER_BASE_URL,
},
ensure_ascii=False,
)
)
async def main() -> None:
while True:
try:
@@ -132,8 +270,16 @@ async def main() -> None:
event = data.get("event")
if event == "generate":
await handle_generate(ws, data)
elif event == "update_code":
await handle_update_code(ws, data)
elif event == "restart_service":
await handle_restart_service(ws, data)
elif event == "ping":
await handle_ping(ws, data)
elif event == "registered":
print("registered", data)
except SystemExit:
return
except Exception as exc:
print("connection error, retry in 3s:", exc)
time.sleep(3)