Enhance backend configuration and sanitization logic

- Updated the `recover_errored_backends` function to preserve `ExtraArgs` during backend reconfiguration, improving error recovery.
- Refined the `sanitize_backends_fds` function to prevent newline merging issues with bare `\\x` entries, ensuring correct FDS formatting.
- Enhanced the `configure_comfy_backend` function to accept and manage `ExtraArgs`, preventing loss of important configuration during recovery.
- Added tests to validate the new sanitization behavior and ensure that bare `\\x` entries remain intact, improving overall backend management.
This commit is contained in:
Leonid Pershin
2026-08-21 11:50:01 +03:00
parent 021feaa839
commit b9059cd275
3 changed files with 41 additions and 22 deletions
+21 -8
View File
@@ -263,10 +263,12 @@ def recover_errored_backends(*, wait_sec: float = 180.0) -> str:
return "errored"
else:
for bid, meta in entries:
script = str((meta.get("settings") or {}).get("StartScript") or "")
settings = meta.get("settings") or {}
script = str(settings.get("StartScript") or "")
extra = str(settings.get("ExtraArgs") or "")
print(f"reconfigure errored id={bid} old StartScript={script!r}", flush=True)
try:
configure_comfy_backend(sid, bid)
configure_comfy_backend(sid, bid, extra_args=extra)
except Exception as exc:
print(f"configure FAIL id={bid}: {exc}", flush=True)
@@ -328,7 +330,11 @@ def recover_errored_backends(*, wait_sec: float = 180.0) -> str:
def sanitize_backends_fds() -> bool:
"""Repair ExtraArgs: \\x --flag (FDS empty + appended flag). Return True if changed."""
"""Repair ExtraArgs: \\x --flag (FDS empty + appended flag). Return True if changed.
Do not use ``\\s`` after ``\\x`` — newline would be eaten and merge FDS keys.
Bare ``ExtraArgs: \\x`` is valid empty and must be left alone.
"""
path = DATA / "Data" / "Backends.fds"
if not path.is_file():
return False
@@ -336,8 +342,8 @@ def sanitize_backends_fds() -> bool:
text = path.read_text(encoding="utf-8")
except OSError:
return False
new, n = re.subn(r"^(\s*ExtraArgs:\s*)\\x(\s+)", r"\1", text, flags=re.M)
if not n:
new, n = re.subn(r"^(\s*ExtraArgs:\s*)\\x[ \t]+", r"\1", text, flags=re.M)
if not n or new == text:
return False
path.write_text(new, encoding="utf-8")
print(f"sanitized Backends.fds ExtraArgs \\x corruption ({n} line(s))", flush=True)
@@ -449,12 +455,18 @@ def toggle_backend(sid: str, backend_id: int, *, enabled: bool) -> dict:
)
def configure_comfy_backend(sid: str, backend_id: int) -> None:
def configure_comfy_backend(
sid: str, backend_id: int, *, extra_args: str | None = None
) -> None:
"""Set StartScript after AddNewBackend (defaults are empty → stays disabled)."""
script = comfy_start_script()
# Preserve ExtraArgs (e.g. --use-sage-attention); "" wipes sage every recover.
extra = "" if extra_args is None else str(extra_args).strip()
if extra in {"\\x", "x"}:
extra = ""
settings = {
"StartScript": script,
"ExtraArgs": "",
"ExtraArgs": extra,
"DisableInternalArgs": False,
"AutoUpdate": "false",
"UpdateManagedNodes": "false",
@@ -551,7 +563,8 @@ def recover_empty_backends() -> str:
flush=True,
)
try:
configure_comfy_backend(sid, bid)
extra = str(settings.get("ExtraArgs") or "")
configure_comfy_backend(sid, bid, extra_args=extra)
except Exception as exc:
print(f"configure FAIL id={bid}: {exc}", flush=True)
+9 -14
View File
@@ -84,26 +84,21 @@ def find_pip() -> Path | None:
def sanitize_backends_fds() -> bool:
"""Repair ``ExtraArgs: \\x --flag`` and bare ``ExtraArgs: \\x`` → clean values."""
"""Repair ``ExtraArgs: \\x --flag`` only. Bare ``\\x`` is valid FDS empty.
Important: do not use ``\\s+`` after ``\\x`` — that eats the newline and
merges the next FDS key onto the ExtraArgs line (breaks SwarmUI load).
"""
if not BACKENDS.is_file():
return False
text = BACKENDS.read_text(encoding="utf-8")
new = text
# ``ExtraArgs: \x --flags`` → ``ExtraArgs: --flags``
new, n1 = re.subn(
r"^(\s*ExtraArgs:\s*)\\x(\s+)",
# Only horizontal whitespace after \x (spaces/tabs), never newline.
new, n = re.subn(
r"^(\s*ExtraArgs:\s*)\\x[ \t]+",
r"\1",
new,
text,
flags=re.M,
)
# Bare empty marker left alone is OK for Swarm, but normalize trailing junk.
new, n2 = re.subn(
r"^(\s*ExtraArgs:\s*)\\x\s*$",
r"\1",
new,
flags=re.M,
)
n = n1 + n2
if n and new != text:
BACKENDS.write_text(new, encoding="utf-8")
print(f"sanitized Backends.fds ExtraArgs \\x corruption ({n} line(s))")
+11
View File
@@ -178,6 +178,17 @@ def test_sanitize_backends_fds_corruption(tmp_path, monkeypatch):
assert backends.read_text(encoding="utf-8") == "ExtraArgs: --use-sage-attention\n"
def test_sanitize_does_not_eat_newline_on_bare_empty(tmp_path, monkeypatch):
"""Bare FDS empty ``\\x`` must not match — ``\\s+`` would merge next key."""
mod = _load()
backends = tmp_path / "Backends.fds"
original = "\tExtraArgs: \\x\n\tStartScript: /mnt/swarm_data/dlbackend/ComfyUI/main.py\n"
backends.write_text(original, encoding="utf-8")
monkeypatch.setattr(mod, "BACKENDS", backends)
assert mod.sanitize_backends_fds() is False
assert backends.read_text(encoding="utf-8") == original
def test_ensure_absolute_start_script(tmp_path, monkeypatch):
mod = _load()
data = tmp_path