Commit Graph
17 Commits
Author SHA1 Message Date
stroblme 03670c782f Backend CI tests on Python 3.12 and 3.14, with the extras installed
A matrix of the declared floor and the newest release in place of 3.13
alone. The job now syncs --all-extras like `make test-backend`, since the
mail, MQTT and Influx tests fail on a fresh venv without the server extra.
Both packages list 3.14 among their classifiers.
2026-10-15 15:56:59 +02:00
stroblme ed8aee2387 Authenticate sockets by header or one-time ticket instead of ?token= 2026-10-07 08:58:22 +02:00
stroblme 3f818c878c Back to development 2026-10-03 11:55:17 +02:00
stroblme e5a9a3738d Release v0.1.6
Publish / publish (push) Failing after 39s
2026-10-03 11:51:21 +02:00
stroblme 8e62c7726b Back to development 2026-09-02 22:48:40 +02:00
stroblme a45f88de1a Release v0.1.5
Publish / publish (push) Failing after 39s
2026-09-02 22:47:33 +02:00
stroblme f3b4c8a1b3 Back to development: 0.1.4+dev
A tag is the only thing that is a version. Between two of them the tree is a
build nobody released, and until now it went on claiming to *be* the release
it came after — which is how 0.1.4 came to name both the build before the
per-node digest and the build after, with the mismatch messages unable to tell
them apart.

`+dev` is a local version: it says "0.1.4, plus changes", it does not have to
guess what the next release will be numbered, and PyPI refuses one, so a dev
build cannot be published by accident. `scripts/release.sh` in the workspace
root writes it after each tag; this is that commit, by hand, for the release
that predates it.
2026-08-28 11:01:25 +02:00
stroblme bda6e25472 Release v0.1.4
Publish / publish (push) Failing after 41s
2026-08-27 23:16:19 +02:00
stroblme 718b32a625 Let a worker say what machine it is
A worker reported its labels and nothing about the machine behind them, so the
engine could route a node to a GPU box but not tell whether that box had a GPU
free. Inventory — cores, GPUs, memory — now arrives with the hello frame, and
the run frame carries back what the engine allocated for that call.

Which is protocol 2 on both ends. GPUs are never probed: asking a vendor tool
would make the one dependency two, so a GPU is what the batch job says it was
given or what --gpus says. A worker that reports nothing still attaches and is
scheduled by its label alone.

Two things a job scheduler needs: --max-idle stops a worker started for one job
rather than letting it hold its allocation to the walltime, and a refusal is now
fatal instead of a reconnect loop that reads as a hang in a job's log.
2026-08-27 08:29:35 +02:00
stroblme c3dcefb04c 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.
2026-08-26 21:19:09 +02:00
stroblme 3f6ff51730 Release v0.1.3
Publish / publish (push) Failing after 42s
2026-08-26 16:05:04 +02:00
stroblme 8a645da974 Release v0.1.2
Publish / publish (push) Failing after 39s
2026-08-25 12:54:41 +02:00
stroblme 91953185ef Release v0.1.1
Publish / publish (push) Failing after 40s
2026-08-24 21:33:18 +02:00
stroblme 449214c0e5 Fix the CI gates: Python 3.13, concurrency groups, hook violations
The gates have never gone green on the new runners. Three separate reasons:

- backend/Dockerfile shipped Python 3.10 while the code imports typing.Self
  and datetime.UTC, so the container exited on import and the suite could not
  even load its conftest. The image moves to 3.13 and the packages declare
  >=3.12, which is the floor the tests actually pass on; ruff's target follows
  and rewrites timezone.utc and asyncio.TimeoutError accordingly. Relocking
  drops the 3.10 branch, which bumps FastAPI and so regenerates the SDK.
- frontend/README.md had no trailing newline and two dashboard widgets used
  arbitrary text-[…] sizes. Both are em-relative on purpose, so they move to
  the inline style the neighbouring ramp already uses.
- Every commit left its own run queued: without a concurrency group a runner
  that was offline for a while works through a backlog nobody reads. A stack
  that fails to come up now prints its logs before the teardown removes it.
2026-08-24 14:55:59 +02:00
stroblme a5a8127550 License the workspace under AGPL-3.0-or-later
Replace the empty LICENSE placeholders with the verbatim GNU AGPL v3 text,
fix the invalid "AGPLv3" SPDX string in the package metadata, and name
Melvin Strobl as the copyright holder wherever the old footers said
"Fluksio ... all rights reserved".
2026-08-24 11:53:54 +02:00
stroblme 694731de15 Make both distributions fit to publish
The release workflow was already right; what it would have uploaded was not.
`fluksio` had no readme, so its PyPI page would have been blank — the app
repo's own README is a contributor's map of `frontend/` and `docker/`, which
is the wrong front page for `pip install fluksio`. It now has one of its own,
aimed at somebody who landed on the project page. Both distributions gain
authors, urls, keywords and classifiers; `twine check` passes clean on all
four artifacts where it warned on two before.

The workflow publishes `fluksio-worker` first, because `fluksio` depends on it
and the other order leaves a few seconds — the whole of a first release — in
which the dependency cannot be resolved. `--check-url` makes a re-run skip
what is already uploaded rather than failing on it, which matters because a
version on PyPI can never be replaced.

Licence metadata is deliberately still absent: LICENSE is MIT in somebody
else's name, inherited from the template this was scaffolded from, and whose
it should be is not a decision to make in a commit. NOTEPAD carries it.
2026-08-24 11:21:33 +02:00
stroblme e3171f87e2 Split the worker into a distribution of its own
A cluster or GPU host installs `pip install fluksio-worker` and gets the
agent and the runner, not psycopg, numpy and the MCP SDK. The engine
depends on it as a workspace member, so the file it launches node code
with is the same file a remote worker runs — which is what keeps a node
unable to tell the difference. Copying the two files by hand still works.
2026-08-21 21:54:10 +02:00