mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-27 08:12:22 +01:00
feat(photo-editor): NL editor planner, image ops, email/gallery server
Server-side photo editor: natural-language editor agent route
(/api/editor/agent), photo_editor tool family + style guide, image-op
provider proxy with progress, email server hardening, gallery/hwfit
routes, and graceful shutdown.
Source: vendor/photocraft (ad1cff44) editor-server files, merged onto
upstream/dev (a8c147b2). Conflict resolution documented in
pr_work/B_conflicts.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c74f475679
commit
eb940f24a3
@@ -0,0 +1,61 @@
|
||||
"""In-flight activity counters (heavy image ops) for safe restarts/observability.
|
||||
|
||||
A deploy restart kills any in-flight long image op (a diffusion edit is 60-120 s),
|
||||
so the operator needs to know whether the process is busy before issuing
|
||||
``systemctl --user restart``. These counters are process-local and cheap.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
from typing import Dict
|
||||
|
||||
_lock = threading.Lock()
|
||||
_image_ops = 0
|
||||
_image_ops_by_name: Dict[str, int] = {}
|
||||
_started_at = time.time()
|
||||
|
||||
|
||||
def begin_image_op(name: str = "image") -> None:
|
||||
global _image_ops
|
||||
with _lock:
|
||||
_image_ops += 1
|
||||
_image_ops_by_name[name] = _image_ops_by_name.get(name, 0) + 1
|
||||
|
||||
|
||||
def end_image_op(name: str = "image") -> None:
|
||||
global _image_ops
|
||||
with _lock:
|
||||
_image_ops = max(0, _image_ops - 1)
|
||||
if name in _image_ops_by_name:
|
||||
_image_ops_by_name[name] -= 1
|
||||
if _image_ops_by_name[name] <= 0:
|
||||
_image_ops_by_name.pop(name, None)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def image_op(name: str = "image"):
|
||||
begin_image_op(name)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
end_image_op(name)
|
||||
|
||||
|
||||
def activity() -> Dict[str, object]:
|
||||
with _lock:
|
||||
return {
|
||||
"image_ops": _image_ops,
|
||||
"image_ops_by_name": dict(_image_ops_by_name),
|
||||
"uptime_s": round(time.time() - _started_at, 1),
|
||||
}
|
||||
|
||||
|
||||
def heavy_image_ops_active() -> int:
|
||||
with _lock:
|
||||
return _image_ops
|
||||
|
||||
|
||||
def busy() -> bool:
|
||||
return heavy_image_ops_active() > 0
|
||||
Reference in New Issue
Block a user