diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-09 14:28:40 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-09 14:28:40 +0200 |
| commit | 7e2d078fe1870d256ae47781bee6ac4f454edf24 (patch) | |
| tree | 05689049fd48f01ebbdb9995d5189cba15cee052 /packages/meshbay-common/src/meshbay_common/__init__.py | |
| parent | 813d18424ec57963bb56e6f40824a2db0ccce50d (diff) | |
| parent | e6f895c473a0b19e7b186889c1836d3945bc880b (diff) | |
| download | meshbay-7e2d078fe1870d256ae47781bee6ac4f454edf24.tar.gz | |
Merge branch 'fix/large-download-paths'
Concurrent-transfer limits, with the queue, the pause and the flag day.
A node now caps how many transfers it runs at once (8 downloads, 8 uploads,
node-wide) and how many one member may run in one group (2 by default,
operator-signed). Beyond that the node answers "queued" and the client waits its
turn, visibly, in the transfers panel — and a slot that frees starts whatever is
next, skipping past a member who is at their own cap rather than letting them
stall everyone behind them.
Browsing is never subject to a slot: not the poster grid, not the covers, not
opening a photo to look at it. That is structural — a transfer is what the
transfers widget shows — and the exemption is bounded rather than open, at two
files in flight per session, because an exemption with no bound is a leaseless
branch under another name.
Transfers can be cancelled, and now paused and resumed. A paused one holds
nothing: its slot goes back at once and resuming rejoins the queue at the tail.
Uploads survive the connection that started them and resume where the node
stopped, asked for inside the seal rather than on a clear message. What they
leave behind when they are abandoned is reaped, which closes a disk leak that
predates this work.
MNP 3.0 makes the lease compulsory and refuses 2.x at the handshake, with the
desktop client checking `client.minimum` before connecting so an un-updated one
says "update" instead of failing every connection in a protocol vocabulary.
Fourteen defects were found on the way, eight of them by a person clicking
Download and pasting a console — none of which 2075 tests could reach. Section
12 of ~/next/improve-downloads.md is that report, including the three this work
introduced itself and the one that turned out to be caused by an instruction to
hard-reload after each deployment.
Node suite 1209 passed, hub suite 866 passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCGdheDLxGReuKHga3BtST
Diffstat (limited to 'packages/meshbay-common/src/meshbay_common/__init__.py')
| -rw-r--r-- | packages/meshbay-common/src/meshbay_common/__init__.py | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/__init__.py b/packages/meshbay-common/src/meshbay_common/__init__.py index b64a6f2..1aaa269 100644 --- a/packages/meshbay-common/src/meshbay_common/__init__.py +++ b/packages/meshbay-common/src/meshbay_common/__init__.py @@ -1,6 +1,6 @@ """MeshBay common — shared crypto primitives and protocol types.""" -__version__ = "0.12.0" +__version__ = "0.13.0" # 0.2: added PING/PONG, and `before`/`has_more` on chat history. Both are # additive — an 0.1 peer sends no `before` and gets the newest page, which is # what it wanted — so this is a MINOR bump, not a MAJOR one. @@ -133,5 +133,37 @@ __version__ = "0.12.0" # `index_progress` (counters only — see daemon.py `_push_index_progress`), the # admin and configuration acks, and the media-metadata replies. The index at # rest and file content on the operator's disk are unchanged. -MNP_VERSION = "2.0" +# **3.0 (2026-09-09): a transfer needs a lease, and a peer that cannot ask for +# one is refused at the handshake.** +# +# `transfer_open` / `transfer_close` / `transfer_state` carry the lease a +# download or an upload runs under; `file_req` gains an optional `tr` and +# `file_upload` gains one beside the `upload_id` already in clear. All three are +# in clear, like `index_progress` and for the same stated reason: `tr` is +# opaque, `bytes` and `chunks` are numbers, and there is no filename and no path +# anywhere in them. Putting one there to make a log line prettier is exactly the +# trade `groupbox.py` exists to refuse. +# +# **The messages are additive; the requirement is not, and that is what makes +# this MAJOR.** A 2.0 client sends no `tr`, so it is a leaseless reader — and a +# leaseless reader is either refused as soon as it opens a third file, or it is +# not refused and transfers outside every cap the operator set. An opt-in switch +# ("enforce leases only for clients that speak 3.0") leaves that branch +# reachable on every node, which is finding C6's lesson — a transport that +# accepted a bare JWT — one feature later. It was already refused once, for chat +# encryption, on 2026-09-07. +# +# Browsing is deliberately **not** leased and never will be: not the poster +# grid, not the covers, not opening a photo to look at it. That exemption is +# bounded rather than open (`transfers.LeaselessReads`, two files in flight per +# session), because an exemption with no bound is the leaseless branch under +# another name. +# +# **What it costs, stated plainly.** The SPA is served by the hub, so a browser +# picks up the new client on reload. The desktop client ships its own UI, so an +# un-updated one is locked out — which is why `GET /v1/hub/version` carries +# `client.minimum` and the client checks it *before* connecting, and says "this +# version can no longer connect" rather than showing a handshake refusal nobody +# can act on. +MNP_VERSION = "3.0" MHP_VERSION = "0.1" |