Parents and children of check-in [a96fe486ab]
|
2026-05-19
| ||
| 16:25 |
feat(hub): Hub.EnsureUser — idempotent user-table registration (closes #183) (#184)
Add Hub.EnsureUser(login, caps string) error as an idempotent counterpart to Hub.AddUser. Consumers (sesh, others) need "register if absent" semantics; AddUser errors on duplicate, forcing each consumer to write check-then-act + race-recheck wrappers. The user-table layer is the right place to own that idempotency. Implementation choice (a) — GetUser → CreateUser, serialized by a Repo- level mutex. Picked over (b) "catch CreateUser's already-exists error" because libfossil's CreateUser surfaces a wrapped SQLite UNIQUE-constraint error with no sentinel or typed shape — string-matching would be brittle. A defensive GetUser retry after CreateUser failure absorbs the rare cross- process race where the in-process mutex doesn't apply. Contract: existing caps are PRESERVED on duplicate (documented). Callers wanting replace-on-conflict use SetUserCaps explicitly. Tests cover first-time registration, duplicate no-op, caps-change-on- duplicate (preservation), 5-goroutine concurrent race (exactly one row lands), and empty-login rejection. Full hub package + leaf + bridge + CLI suites pass; go vet clean; gofmt clean. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 40c9b9aff3 user: [email protected] tags: trunk, main | |
|
2026-05-17
| ||
| 18:47 |
fix(hub): address pulls to publishing peer to resolve .sync race (#162) (#181)
Three+ hubs sharing a project-code all subscribed to the same broadcast
`<prefix>. Two changes close the gap:
The receiver also drops self-notifications (a publish from this hub
round-tripping back via an upstream leaf, which NoEcho doesn't catch
across leaf links) and notifications missing a peer-id (older publisher
that pre-dates this fix — refusing rather than falling back to a
broadcast pull keeps #162 from regressing silently).
`TestCrossLeaf_ThreeHubs_CommitAnnouncePropagatesToAll` is now ungated:
it ran red under both -short and full modes before this fix, and passes
under both modes (and 10x stability check) after.
Closes #162
Closes #179
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | |
| 17:44 |
test(hub): add 3-hub cross-leaf propagation test (#180)
Mirrors the 2-node TestCrossLeaf_SharedProjectCode_PropagatesCommit shape but with a third leaf attached to the same topology root. Asserts that a commit on any peer propagates to BOTH of the other two peers, both directions. Reproduces the cross-leaf propagation gap reported in #179 and confirms its underlying cause is the multi-responder .sync race filed as #162: with 3+ hubs subscribing to the same .sync subject every peer answers nats.Request, only the first reply wins, and a stale responder silently starves the pull. The first hop (B -> A) is already enough to surface this — A's .sync request can race against C's empty responder even though A and B are the only nodes that need to talk for that direction. Gated under -short with a skip pointing to #162 so pre-commit and CI stay green. Without -short the test fails at the 10s wait in ~10s, demonstrating the bug. Remove the skip once #162 is fixed; the test then doubles as the regression sentinel for the 3+ hub topology that production sesh relies on. No production code changes. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> check-in: 5c36d5498d user: [email protected] tags: trunk, main | |