diff --git a/.env.example b/.env.example index 7601dce..46bde6b 100644 --- a/.env.example +++ b/.env.example @@ -39,7 +39,5 @@ OIDC_AUDIENCES= # --- Cache process management ---------------------------------------------- # Path to the fastcache executable; bare name = resolved via PATH. FASTCACHE_BINARY=lclstream-fastcache -# Directory where per-cache config/log files are written. -RUN_DIR=run # Grace period (seconds) before escalating SIGTERM to SIGKILL on shutdown. SHUTDOWN_GRACE_SECONDS=5.0 diff --git a/src/fastcache_api/config.py b/src/fastcache_api/config.py index 4523e42..ca43fbc 100644 --- a/src/fastcache_api/config.py +++ b/src/fastcache_api/config.py @@ -51,8 +51,6 @@ class Settings(BaseSettings): # Cache process management # Path to the fastcache executable (overridable; defaults to PATH lookup). FASTCACHE_BINARY: Path = Path("lclstream-fastcache") - # Directory where per-cache config/log files are written. - RUN_DIR: Path = Path("run") # Grace period before escalating SIGTERM to SIGKILL on shutdown. SHUTDOWN_GRACE_SECONDS: float = 5.0 # How often the liveness poller checks running caches against their pids. diff --git a/src/fastcache_api/models.py b/src/fastcache_api/models.py index b7aa1dd..e303dd8 100644 --- a/src/fastcache_api/models.py +++ b/src/fastcache_api/models.py @@ -54,6 +54,8 @@ class CacheRequest(BaseModel): # Human who initiated the transfer upstream (bearer token is a shared # service identity, so attribution must travel in the request body). requested_by: str + # Absolute path the orchestrator dictates for this cache's log. + log_path: Path class CachePublic(BaseModel): diff --git a/src/fastcache_api/process.py b/src/fastcache_api/process.py index efd5572..d638602 100644 --- a/src/fastcache_api/process.py +++ b/src/fastcache_api/process.py @@ -3,6 +3,7 @@ import socket import subprocess from collections.abc import Iterable +from pathlib import Path from uuid import UUID import psutil @@ -35,17 +36,18 @@ def allocate_port_pair(in_use: set[int], start: int, end: int) -> tuple[int, int raise RuntimeError(f"no free cache port pair in range [{start}, {end}]") -def start_cache(cache_id: UUID, config: CacheConfig) -> CacheProcess: - run_dir = settings.RUN_DIR / str(cache_id) +def start_cache(cache_id: UUID, config: CacheConfig, log_path: Path) -> CacheProcess: + run_dir = log_path.parent run_dir.mkdir(parents=True, exist_ok=True) config_path = run_dir / "config.json" config_path.write_text(config.to_fastcache_json()) - log_path = (run_dir / "cache.log").resolve() + log_path = log_path.resolve() with log_path.open("ab") as log_file: proc = subprocess.Popen( [settings.FASTCACHE_BINARY, config_path], + cwd=run_dir, stdout=log_file, stderr=subprocess.STDOUT, start_new_session=True, diff --git a/src/fastcache_api/routes/cache.py b/src/fastcache_api/routes/cache.py index d475130..dc1af8a 100644 --- a/src/fastcache_api/routes/cache.py +++ b/src/fastcache_api/routes/cache.py @@ -91,7 +91,7 @@ async def create_cache( cache_id = uuid4() try: - proc = start_cache(cache_id, config) + proc = start_cache(cache_id, config, req.log_path) except (FileNotFoundError, OSError, RuntimeError) as exc: raise HTTPException( status_code=status.HTTP_503_SERVICE_UNAVAILABLE,