Remote tracking (spool-and-flush)¶
Track runs on one machine, store and watch them on another. Design rationale: the design document §9. The model is spool-and-flush: nothing ever writes to the network directly — every writer uses a normal local store (the spool), and a flusher ships the delta to the server. Offline runs, crashes, and lost connections lose nothing; the spool keeps everything until it’s shipped, and every shipment is idempotent, so retrying is always safe.
Server (machine S)¶
# authenticated mode — users, roles, per-user tokens:
mlp user add paul --role admin --root /srv/mlparty/.mlparty
mlp token create --user paul --name train-box --root /srv/mlparty/.mlparty
mlp serve --root /srv/mlparty/.mlparty
# or legacy single-token mode (trusted networks only — reads stay open):
mlp serve --root /srv/mlparty/.mlparty --generate-token
mlp serve is mlp ui plus the authenticated sync-ingest API — same web
viewer, same read API. With users configured, everything is login-gated:
humans sign into the web UI, sync clients authenticate with a per-user
token, and ingest needs the writer role (see Deployment for
roles/administration). Keep it localhost-bound and tunnel over SSH, or put
TLS in front before exposing it; credentials ride on every request. A
server started with plain mlp ui refuses all sync writes.
Client (machine C or L)¶
Point the spool store at the server in store.toml:
[sync]
url = "http://127.0.0.1:7327" # or the tunneled/TLS address
token_file = "server_token" # or token = "…", or ML_PARTY_TOKEN env
interval_seconds = 10
The token is either a per-user mlp_… token (auth mode — must belong to a
writer) or the legacy shared token; the client doesn’t care which.
That’s all. From then on:
mlparty.attach()flushes in a background thread while the training runs (metrics appear in the server UI within ~one interval) and does a synchronous final flush at finalize/fail.mlp syncships anything left over — after a crash, an offline run, or for stores nothing is attached to. Run it any time; it converges. Override ad hoc withmlp sync --to URL --token ….
What ships, and why it’s safe¶
Stream |
Addressing |
Retry behavior |
|---|---|---|
journal events |
ULID id per event |
server dedupes; replays are no-ops |
git snapshots |
content (sha) + |
missing-negotiation; re-push skips |
artifacts |
content (sha256) |
deduped on existence, hash-verified |
metrics |
byte offset per run |
cursor advances only on ack; conflicts resume from the server’s size |
Events are preserved verbatim — authorship (created_by) and timestamps
survive the hop; the git model applies (the event’s created_by is the
author, the authenticated token user is the transport identity that
shipped it). Sync cursors live in the spool’s sync_state.json; deleting
it merely causes a harmless full replay.
Caveats¶
One spool per run: two spools syncing the same run’s metrics to one server is detected and refused (offset conflict) — knowledge-graph events from many spools merge fine.
In legacy single-token mode the server trusts the token entirely and the read API is open — trusted networks only. Configure users for per-user identity and login-gated reads.