mesh/delivery held for a person: merged without a passing check: only a person decides what follows
mesh/check checking e9a885cda925 on 62802cd96602
At 16:07:36 the builder rewrote about 120 done keys at once. Each woke a take-in of its own with no limit, and each take-in read the rest of the mesh through restOfTheMeshOf, which opened a licences and an identity pool per call. novox's store ran out of connections at 16:08 and refused everyone, the controller's retries keeping it full. - The serving controller lends its stores by inventory (shareStores); restOfTheMeshOf reads on them instead of opening pools per call, and a verb run as its own process still opens its own. stores opens each store once under a lock, since readers now share it. serve uses the shared identity store instead of a second pool. - The watch's take-ins and the start's look share one cap of 16 take-ins at once (takeInSlots); a take-in waiting for its next try holds none. - store.Ready backs off on a full store (SQLSTATE 53300), doubling its wait up to 5 s, and says once that the store is full. Issues 1945 and 1277.
87 lines
3.1 KiB
Go
87 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"github.com/novox/mesh-controller/internal/identity"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/licences"
|
|
)
|
|
|
|
// The serving controller's reads of the rest of the mesh open no pool per call: the licences and identity stores are the
|
|
// controller's own, opened once and shared. On 2026-10-25 at 16:08 each take-in opened two pools of its own
|
|
// (restOfTheMeshOf), about 120 at once, and novox's store refused every new connection (issues 1945 and 1277).
|
|
func TestRestOfTheMeshOfOpensNoPoolPerCall(t *testing.T) {
|
|
wasIdent, wasLic, wasRest := identityOpener, licencesOpener, restOfTheMeshOn
|
|
t.Cleanup(func() { identityOpener, licencesOpener, restOfTheMeshOn = wasIdent, wasLic, wasRest })
|
|
var identities, licencesOpened atomic.Int64
|
|
identityOpener = func(context.Context) (*identity.Identity, error) {
|
|
identities.Add(1)
|
|
return &identity.Identity{}, nil
|
|
}
|
|
licencesOpener = func(context.Context) (*licences.Licences, error) {
|
|
licencesOpened.Add(1)
|
|
return &licences.Licences{}, nil
|
|
}
|
|
// The read of the Input reaches both stores, as readComposeInput does.
|
|
restOfTheMeshOn = func(ctx context.Context, open *stores, _ map[string]catalogue.Manifest, _ string) (catalogue.World, error) {
|
|
if _, err := open.Licences(ctx); err != nil {
|
|
return catalogue.World{}, err
|
|
}
|
|
if _, err := open.Identity(ctx); err != nil {
|
|
return catalogue.World{}, err
|
|
}
|
|
return catalogue.World{}, nil
|
|
}
|
|
inv := &inventory.Inventory{}
|
|
serving := &stores{inventory: inv}
|
|
unshare := shareStores(serving)
|
|
t.Cleanup(unshare)
|
|
|
|
var wg sync.WaitGroup
|
|
for range 120 {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
if _, err := restOfTheMeshOf(context.Background(), inv, nil, ""); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
if n := licencesOpened.Load(); n != 1 {
|
|
t.Fatalf("opened the licences store %d times for 120 reads, want once", n)
|
|
}
|
|
if n := identities.Load(); n != 1 {
|
|
t.Fatalf("opened the identity store %d times for 120 reads, want once", n)
|
|
}
|
|
if serving.licences == nil || serving.identity == nil {
|
|
t.Fatal("the reads did not use the serving controller's stores")
|
|
}
|
|
}
|
|
|
|
// A process that shares no stores (a verb run as its own short process) still opens them for the call and lets go.
|
|
func TestRestOfTheMeshOfOpensItsOwnWhereNoneAreShared(t *testing.T) {
|
|
wasIdent, wasLic, wasRest := identityOpener, licencesOpener, restOfTheMeshOn
|
|
t.Cleanup(func() { identityOpener, licencesOpener, restOfTheMeshOn = wasIdent, wasLic, wasRest })
|
|
var opened atomic.Int64
|
|
licencesOpener = func(context.Context) (*licences.Licences, error) { opened.Add(1); return &licences.Licences{}, nil }
|
|
restOfTheMeshOn = func(ctx context.Context, open *stores, _ map[string]catalogue.Manifest, _ string) (catalogue.World, error) {
|
|
_, err := open.Licences(ctx)
|
|
return catalogue.World{}, err
|
|
}
|
|
inv := &inventory.Inventory{}
|
|
for range 2 {
|
|
if _, err := restOfTheMeshOf(context.Background(), inv, nil, ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if n := opened.Load(); n != 2 {
|
|
t.Fatalf("opened %d times, want once per call", n)
|
|
}
|
|
}
|