A node's bucket opens under its own deadline, so a per-node page is ended by its budget too (issue 1966)
mesh/delivery merged: source.main moved to novox/mesh-tools@164547645aed
mesh/delivery-group group fix/1966-views-page-time merged: every member is merged
mesh/check checking 2135fed6cf1f on 9f61975c50a0 | novox/mesh-tools#64 in group fix/1966-views-page-time

Review round 3: the open on the first key of a node ran on the listing's context,
whose deadline is spent before the page's budget.

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-09 09:04:39 +01:00
parent aba2c11a27
commit 2135fed6cf
+5 -1
View File
@@ -166,6 +166,7 @@ func (c *Conn) StatePage(module, name, after string, maxBytes int, budget time.D
} }
// The bind and the listing have a StateTimeout of their own, and each get another: the page's time budget is what // The bind and the listing have a StateTimeout of their own, and each get another: the page's time budget is what
// ends a slow page (with Next), never a deadline spread over the whole of it. // ends a slow page (with Next), never a deadline spread over the whole of it.
// ctx covers the bind and the listing alone; every bus request inside the loop takes each().
ctx, cancel := context.WithTimeout(context.Background(), StateTimeout) ctx, cancel := context.WithTimeout(context.Background(), StateTimeout)
defer cancel() defer cancel()
each := func() (context.Context, context.CancelFunc) { each := func() (context.Context, context.CancelFunc) {
@@ -186,7 +187,10 @@ func (c *Conn) StatePage(module, name, after string, maxBytes int, budget time.D
} }
kv, bound := buckets[node] kv, bound := buckets[node]
if !bound { if !bound {
if kv, err = fam.Open(ctx, node); err != nil { octx, ocancel := each() // the open is a bus request in the loop: its own deadline, never ctx's
kv, err = fam.Open(octx, node)
ocancel()
if err != nil {
return nil, err return nil, err
} }
buckets[node] = kv buckets[node] = kv