diff options
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/transfers.py | 45 | ||||
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py | 6 |
2 files changed, 23 insertions, 28 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transfers.py b/packages/meshbay-node/src/meshbay_node/transfers.py index dd382b4..cef817a 100644 --- a/packages/meshbay-node/src/meshbay_node/transfers.py +++ b/packages/meshbay-node/src/meshbay_node/transfers.py @@ -28,9 +28,8 @@ properties are load-bearing, and each one is a decision: This module is deliberately free of asyncio and of the transport: it decides, and the caller does the I/O. `sweep()` is called on a clock the caller owns, and every method returns what changed so the caller can push it. That is what makes -the failure modes in §5 of ~/next/improve-downloads.md testable at all — a -queue that only reveals itself through a DataChannel is a queue nobody can -prove things about. +the failure modes testable at all — a queue that only reveals itself through a +DataChannel is a queue nobody can prove things about. """ from __future__ import annotations @@ -412,28 +411,24 @@ class TransferSlots: # Browsing a group is never subject to a transfer slot — not the poster grid, # not the covers, not opening a photo or a PDF to look at it. A member must be # able to browse a group that is at capacity exactly as they browse an idle one. -# That is a requirement, and §3.4 of ~/next/improve-downloads.md satisfies it -# structurally: a transfer is what the transfers widget shows, and nothing else -# takes a slot. +# That requirement is met structurally rather than by judgement: a transfer is +# what the transfers widget shows, and nothing else takes a slot. # # But "not leased" cannot mean "unbounded", or a client that simply omits `tr` # transfers outside every cap and the caps are decoration. # -# **The number comes from what the shipped client legitimately does, and it was -# wrong once already.** §3.4.1 of ~/next/improve-downloads.md argued for two, -# reasoning about *viewers*: a photo viewer shows one photo, a preview modal one -# document, and the second is for prefetching the next photo. That reasoning -# forgot the music player, which warms a read-ahead window — `prefetchDepth()` -# in music-player.js returns 5 on Wi-Fi, 3 otherwise — so playing an album has -# six files in flight and the fourth was refused with `transfer_required`. -# Reported the day MNP 3.0 shipped, as "I try to play a track and it tells me to -# download it instead". +# **The number comes from what the client legitimately does**, and reasoning +# about *viewers* alone gets it wrong: a photo viewer shows one photo and a +# preview modal one document, but the music player warms a read-ahead window — +# `prefetchDepth()` in music-player.js returns 5 on Wi-Fi, 3 otherwise — so +# playing an album has six files in flight before anyone has done anything +# unusual, and a bound of two refuses a member trying to play a track. # -# Twelve: six for the music read-ahead at its widest, two for a photo viewer -# and its own prefetch running at the same time in the same session, and the -# rest as headroom for the next app that reads ahead. `test_leaseless_reads.py` -# derives the floor from music-player.js itself, so raising the client's -# prefetch without raising this fails rather than reaching a person. +# Twelve: six for that read-ahead at its widest, two for a photo viewer and its +# own prefetch running at the same time in the same session, and the rest as +# headroom for the next app that reads ahead. `test_leaseless_reads.py` derives +# the floor from music-player.js itself, so raising the client's prefetch +# without raising this fails rather than reaching a person. # # Generosity is cheap here and refusal is not. This is a fairness control among # cooperating clients, not a security boundary — a client that lies gets twelve @@ -445,11 +440,11 @@ class TransferSlots: # size threshold separates them. What separates them is which function asked. # # What it costs, stated plainly: a client that lies — labelling a bulk download -# as a view — gets two files at a time instead of its member cap. That is the -# residual, it is bounded, it is audited, and it is the same kind of statement -# as the cap itself. **This is a fairness control among cooperating clients**, -# not a defence against a member determined to saturate a node's disk. The -# answer to that member is `member revoke`. +# as a view — gets this many files at a time instead of its member cap. That is +# the residual, it is bounded, it is audited, and it is the same kind of +# statement as the cap itself. **This is a fairness control among cooperating +# clients**, not a defence against a member determined to saturate a node's +# disk. The answer to that member is `member revoke`. MAX_LEASELESS_IN_FLIGHT = 12 # A leaseless read has no "close" message, so it ends when the last chunk goes diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py index 46fbba3..b3618b5 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py @@ -4822,9 +4822,9 @@ class WebRTCPeerSession: # 11:54:19 reclaimed 919ebf54 (abandoned) # 11:55:48 Upload complete: ... (3 522 297 517 bytes) # - # The download twin of this was fixed on 2026-09-08 (§12.1 of - # ~/next/improve-downloads.md); the same omission was still here, - # invisible until uploads started taking a real lease. + # `_do_file_request` marks a lease alive for exactly the same reason; + # both sides of a transfer have to say they are still moving, or the + # sweeper reclaims whichever one forgot. tr = msg.get("tr") if tr: slots = self._ctx.get("_transfer_slots") |