Show dataset YOLO output readiness

This commit is contained in:
2026-06-30 15:29:30 +08:00
parent 826027629b
commit b60fcc5112
6 changed files with 175 additions and 12 deletions

View File

@@ -44,6 +44,7 @@ def evaluate_project() -> dict:
"upload_ui": "uploadDatasetFiles" in frontend_text and "labels" in frontend_text and "masks" in frontend_text,
"dataset_quality_ui": "DatasetQuality" in frontend_text and "generateSelectedYoloYaml" in frontend_text,
"uploaded_yolo_workflow_ui": "startSelectedYoloTrain" in frontend_text and "startSelectedYoloPredict" in frontend_text and "startSelectedYoloHeatmap" in frontend_text,
"dataset_yolo_outputs_ui": "DatasetYoloOutputs" in frontend_text and "selectedYoloOutputs" in frontend_text and "BEST.PT READY" in frontend_text,
"loss_result_ui": "loss" in frontend_text.lower() and "heatmap" in frontend_text.lower() and "CurvePanel" in frontend_text,
"job_progress_ui": "JobProgressBar" in frontend_text and "progressTrack" in frontend_text,
"runtime_readiness_ui": "runtimeReadiness" in frontend_text and "环境就绪" in frontend_text,

View File

@@ -14,6 +14,7 @@ import fcntl
from ...config import settings
READINESS_CACHE_SECONDS = 300
READINESS_FAILURE_CACHE_SECONDS = 30
_readiness_cache: tuple[float, dict[str, Any]] | None = None
_readiness_thread_lock = threading.Lock()
@@ -215,18 +216,22 @@ def inspect_conda_env(env_name: str, required_imports: list[dict[str, str]], tim
def get_runtime_readiness(force: bool = False) -> dict[str, Any]:
global _readiness_cache
now = time.time()
if not force and _readiness_cache and now - _readiness_cache[0] < READINESS_CACHE_SECONDS:
cached = dict(_readiness_cache[1])
cached["cached"] = True
return cached
with readiness_probe_lock():
now = time.time()
if not force and _readiness_cache and now - _readiness_cache[0] < READINESS_CACHE_SECONDS:
if not force and _readiness_cache:
cache_ttl = READINESS_CACHE_SECONDS if _readiness_cache[1].get("passed") else READINESS_FAILURE_CACHE_SECONDS
if now - _readiness_cache[0] < cache_ttl:
cached = dict(_readiness_cache[1])
cached["cached"] = True
return cached
with readiness_probe_lock():
now = time.time()
if not force and _readiness_cache:
cache_ttl = READINESS_CACHE_SECONDS if _readiness_cache[1].get("passed") else READINESS_FAILURE_CACHE_SECONDS
if now - _readiness_cache[0] < cache_ttl:
cached = dict(_readiness_cache[1])
cached["cached"] = True
return cached
conda = get_conda_envs()
env_paths = {item["name"]: item["path"] for item in conda.get("envs", [])}
envs: list[dict[str, Any]] = []
@@ -254,6 +259,7 @@ def get_runtime_readiness(force: bool = False) -> dict[str, Any]:
"passed": bool(conda.get("available")) and all(item["passed"] for item in envs),
"generated_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(now)),
"cache_seconds": READINESS_CACHE_SECONDS,
"failure_cache_seconds": READINESS_FAILURE_CACHE_SECONDS,
"cached": False,
"envs": envs,
"specs": {

View File

@@ -71,3 +71,15 @@ def test_runtime_readiness_aggregates_probe_results(monkeypatch):
assert readiness["passed"] is True
assert readiness["envs"][0]["path"] == "/envs/seg_smp"
assert readiness["specs"]["env_files"] == ["envs/seg_smp.yml", "envs/seg_mmcv.yml"]
def test_runtime_readiness_refreshes_stale_failure_cache(monkeypatch):
monkeypatch.setattr(service, "_readiness_cache", (100.0, {"passed": False, "envs": [], "available": True}))
monkeypatch.setattr(service.time, "time", lambda: 100.0 + service.READINESS_FAILURE_CACHE_SECONDS + 1)
monkeypatch.setattr(service, "runtime_environment_specs", lambda: [])
monkeypatch.setattr(service, "get_conda_envs", lambda: {"available": True, "envs": []})
readiness = get_runtime_readiness(force=False)
assert readiness["cached"] is False
assert readiness["passed"] is True