diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-08 22:54:16 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-08 22:54:16 +0200 |
| commit | 6803447a8a5cc7a612d08bb858394fd7ae1b049c (patch) | |
| tree | 565b2ceda2964f0e1395ea254df6014b116723ed /packages/meshbay-node/src/meshbay_node/ops.py | |
| parent | 051100ca32f72dd8f28489e1b6cb084f321b3b54 (diff) | |
| download | meshbay-6803447a8a5cc7a612d08bb858394fd7ae1b049c.tar.gz | |
fix(node): a running transfer keeps its slot, and a dead grant lets go
Two defects in the lease machinery, both found in the node's own log, neither
reachable from any test on either side.
**`touch()` was never called.** The node ignored `tr` on `file_req` entirely, so
`used` stayed False for every download ever made and the sweeper revoked each
grant thirty seconds in — while the file was transferring at 20 MB/s. The pool
was correct and the handlers were correct; the call between them was missing,
which is why neither side's tests could see it.
**The requeue was a permanent cycle.** A revoked grant went back in the queue,
was granted again a millisecond later because there was room, and was revoked
again thirty seconds on. The node logged the same two reclaims every thirty
seconds for as long as it ran — minutes after the transfers involved had
finished. Three chances now, then the lease is closed and the peer told.
`test_the_counter_never_drifts` could not have caught it: nothing drifted, the
same lease simply never left.
A lease that starts being used forgets its earlier misses: a client that took
two grants to get going is slow, not abandoned.
Also `transfers show` reported the module defaults rather than the operator's
values until something had transferred, so `transfers set 2 2` answered
"applied now" and the next line said 0/8 — indistinguishable, from outside,
from the hot-swap that did nothing for months. The test asserted the defaults
and so agreed with the bug; found by typing the command.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCGdheDLxGReuKHga3BtST
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/ops.py')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/ops.py | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/ops.py b/packages/meshbay-node/src/meshbay_node/ops.py index 81b92c7..088ee32 100644 --- a/packages/meshbay-node/src/meshbay_node/ops.py +++ b/packages/meshbay-node/src/meshbay_node/ops.py @@ -1433,16 +1433,28 @@ async def list_transfers(state: dict) -> dict: where it would be tempting to add one. """ webrtc = state.get("webrtc") - slots = getattr(webrtc, "_ctx", {}).get("_transfer_slots") if webrtc else None + ctx = getattr(webrtc, "_ctx", {}) if webrtc else {} + slots = ctx.get("_transfer_slots") if slots is None: from meshbay_node.transfers import ( DEFAULT_MAX_CONCURRENT, DEFAULT_MAX_PER_MEMBER, KINDS) # No pool built means nothing has transferred since the daemon started, # which is a real answer and not an error. - return {"pools": {k: {"in_use": 0, "cap": DEFAULT_MAX_CONCURRENT, - "per_member": DEFAULT_MAX_PER_MEMBER, - "queued": 0} for k in KINDS}, - "leases": []} + # + # The caps still have to be the operator's own. Reporting the module + # defaults here was worse than reporting nothing: `transfers set 2 2` + # answered "applied now", and `transfers show` immediately said 0/8 — + # a setting written, acknowledged and displayed wrong, which reads + # exactly like the hot-swap that did nothing for months. Found by + # running it, not by a test: the test asserted the defaults and so + # agreed with the bug. + return {"pools": { + k: {"in_use": 0, + "cap": int(ctx.get(f"max_concurrent_{k}s") + or DEFAULT_MAX_CONCURRENT), + "per_member": DEFAULT_MAX_PER_MEMBER, + "queued": 0} + for k in KINDS}, "leases": []} return slots.snapshot() |