Добавлены Workers в систему
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"""Local workload adapters. They receive no arbitrary commands from the network."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Protocol
|
||||
|
||||
from .models import ClaimedTask, ProducedArtifact, RunResult
|
||||
|
||||
|
||||
class Runner(Protocol):
|
||||
def run(self, task: ClaimedTask, task_dir: Path) -> RunResult: ...
|
||||
|
||||
|
||||
class SciMeshRunner:
|
||||
"""Allowlisted adapter from coordinator workloads to the local SciMesh CLI."""
|
||||
|
||||
def run(self, task: ClaimedTask, task_dir: Path) -> RunResult:
|
||||
input_path = task_dir / "input"
|
||||
output_path = task_dir / "result.csv"
|
||||
command = [sys.executable, "-m", "scimesh.cli", task.workload, str(input_path)]
|
||||
params = task.parameters
|
||||
if task.workload == "similarity-search":
|
||||
query_id = self._string(params, "query_id")
|
||||
top_k = self._positive_int(params, "top_k", default=20)
|
||||
command += ["--query-id", query_id, "--top-k", str(top_k)]
|
||||
elif task.workload == "similarity-graph":
|
||||
threshold = self._number(params, "threshold")
|
||||
command += ["--threshold", str(threshold)]
|
||||
else:
|
||||
raise ValueError(f"unsupported workload: {task.workload}")
|
||||
command += ["--output", str(output_path)]
|
||||
subprocess.run(command, check=True, cwd=task_dir) # explicit list: never shell=True
|
||||
if not output_path.is_file():
|
||||
raise RuntimeError("SciMesh CLI did not create its result")
|
||||
processed_rows = max(sum(1 for _ in output_path.open(encoding="utf-8")) - 1, 0)
|
||||
return RunResult((ProducedArtifact(output_path, "text/csv"),), {"processed_rows": processed_rows})
|
||||
|
||||
@staticmethod
|
||||
def _string(params: dict[str, object], name: str) -> str:
|
||||
value = params.get(name)
|
||||
if not isinstance(value, str) or not value.strip() or len(value) > 200:
|
||||
raise ValueError(f"{name} must be a non-empty string")
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def _positive_int(params: dict[str, object], name: str, default: int) -> int:
|
||||
value = params.get(name, default)
|
||||
if isinstance(value, bool) or not isinstance(value, int) or value < 1 or value > 100_000:
|
||||
raise ValueError(f"{name} must be a positive integer")
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def _number(params: dict[str, object], name: str) -> float:
|
||||
value = params.get(name)
|
||||
if isinstance(value, bool) or not isinstance(value, (int, float)) or not 0 <= value <= 1:
|
||||
raise ValueError(f"{name} must be a number between 0 and 1")
|
||||
return float(value)
|
||||
Reference in New Issue
Block a user