aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transfers.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-11 15:42:52 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-11 15:43:06 +0200
commit9d38418817d1894b31c93ece0113e503d82167cd (patch)
treeadf4c8126c90d60f6a16724d14eafb80f33d5289 /packages/meshbay-node/src/meshbay_node/transfers.py
parentb39e73cbb279ab0274e8cd0b84304a602fe1d5ef (diff)
downloadmeshbay-9d38418817d1894b31c93ece0113e503d82167cd.tar.gz
feat(node): log what a transfer moved when it ends
One INFO line per lease: bytes, duration, rate, and the SCTP association's window, round trip, losses and T3 expirations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transfers.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transfers.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transfers.py b/packages/meshbay-node/src/meshbay_node/transfers.py
index 3345cb9..477ec92 100644
--- a/packages/meshbay-node/src/meshbay_node/transfers.py
+++ b/packages/meshbay-node/src/meshbay_node/transfers.py
@@ -102,11 +102,24 @@ class Lease:
# later, for ever. Seen doing exactly that in a node's log, every 30 s,
# minutes after the transfers involved had finished.
missed_grants: int = 0
+ # What moved under this lease and over how long, for the line the node logs
+ # when it ends. Counted here because nothing else spans a transfer: a
+ # download is a run of independent chunk requests.
+ moved: int = 0
+ first_used: float | None = None
+ last_moved: float = 0.0
@property
def member(self) -> tuple[str, str]:
return (self.group_id, self.user_id)
+ @property
+ def elapsed(self) -> float:
+ """Seconds from the first request under this lease to the last byte."""
+ if self.first_used is None:
+ return 0.0
+ return max(0.0, self.last_moved - self.first_used)
+
@dataclass
class TransferSlots:
@@ -223,8 +236,18 @@ class TransferSlots:
lease.used = True
lease.missed_grants = 0
lease.last_seen = time.monotonic() if now is None else now
+ if lease.first_used is None:
+ lease.first_used = lease.last_seen
return True
+ def account(self, tr: str, nbytes: int, now: float | None = None) -> None:
+ """`nbytes` were served or received under this lease."""
+ lease = self.leases.get(tr)
+ if lease is None:
+ return
+ lease.moved += nbytes
+ lease.last_moved = time.monotonic() if now is None else now
+
def close(self, tr: str, reason: str = REASON_DONE,
now: float | None = None) -> tuple[Lease | None, list[Lease]]:
"""Give a slot back. Returns (the closed lease, newly granted ones).