Files
app/worker/pyproject.toml
T
stroblmeandClaude Opus 5 1f7c6646f1 Survive a busy engine: retry, idempotent submit, resilient waiting
A driver script died of one slow answer: httpx.ReadTimeout out of
RunHandle.refresh() with a 30 s read timeout and no retry anywhere, which
cost a sweep 78 of its 84 runs.

- Split the timeout (5 s connect, 120 s read): a wrong URL fails at once,
  and a busy engine gets longer than the slowest thing it does on purpose
  (a 60 s compile, a 15 s rebuild wait).
- Retry idempotent calls three times on a transport error or 502/503/504.
  503 is the engine's own "ask again" — it is what RebuildBusy answers.
- Submit carries a key the engine stores with the run, so a retry after a
  timeout returns that run instead of starting a second. A sweep keys every
  entry, so a half-created one recreates only what is missing.
- wait() and --follow tolerate five failed polls in a row; a 404 still stops
  at once, because that is an answer rather than a gap.
- CLI says "engine not answering" and names the run still on the engine,
  instead of printing a traceback.
- runs: clamp the params column to 80 characters; events() takes the
  flow/since/until the endpoint already had; RunHandle.failures answers
  "what killed this run" from the run's own node rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 21:19:09 +02:00

53 lines
1.6 KiB
TOML

[project]
name = "fluksio-worker"
version = "0.1.4"
description = "Runs Fluksio nodes on a machine the engine cannot reach"
readme = "README.md"
license = "AGPL-3.0-or-later"
license-files = ["LICENSE"]
requires-python = ">=3.12"
authors = [{ name = "Fluksio", email = "stroblme@posteo.de" }]
keywords = ["automation", "workflow", "distributed", "worker", "gpu"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Home Automation",
"Topic :: Scientific/Engineering",
"Topic :: System :: Distributed Computing",
]
dependencies = [
"websockets>=12",
]
[project.urls]
Homepage = "https://fluksio.com"
Documentation = "https://docs.fluksio.com/code/workers/"
[project.scripts]
fluksio-worker = "fluksio_worker.agent:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["fluksio_worker"]
[tool.ruff]
# The engine's config, so both distributions are linted the same way.
extend = "../backend/pyproject.toml"
[tool.ruff.lint.per-file-ignores]
# This one takes its own directory off sys.path before the rest of its imports
# run, which is the whole point of doing it there.
"fluksio_worker/worker_main.py" = ["E402"]
# Copied onto another machine it has no logger configured before it tells you
# the one dependency it is missing.
"fluksio_worker/agent.py" = ["T201"]