Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cc428bf
feat(multidb): add MultiDBClient orchestration layer
ndyakov Aug 5, 2026
2b70a42
fix(multidb): check closeAll error returns in constructor cleanup
ndyakov Aug 5, 2026
95bc3c2
fix(multidb): address review feedback on pubsub, locking and cluster SCH
ndyakov Aug 5, 2026
5517f5f
fix(multidb): address second review round and detector flake
ndyakov Aug 5, 2026
ac3e361
fix(multidb): outcome classification and selection races from review
ndyakov Aug 5, 2026
1332953
fix(multidb): startup breaker reconciliation and lifecycle review fixes
ndyakov Aug 5, 2026
dfc0be1
fix(multidb): third review round on the core
ndyakov Aug 5, 2026
441a6ad
fix(multidb): fourth review round on the core
ndyakov Aug 5, 2026
e5fae64
fix(multidb): fifth review round on the core
ndyakov Aug 6, 2026
faedc15
fix(multidb): sixth review round on the core
ndyakov Aug 6, 2026
b32ee81
fix(multidb): seventh review round on the core
ndyakov Aug 6, 2026
f84285a
fix(multidb): eighth review round on the core
ndyakov Aug 6, 2026
8dfc878
fix(multidb): ninth review round on the core
ndyakov Aug 6, 2026
64b0b54
fix(multidb): survive panicking circuit-state callbacks
ndyakov Aug 6, 2026
e5255fa
fix(multidb): harden failover races from final review pass
ndyakov Aug 6, 2026
8704488
fix(multidb): membership cancellation and stale-callback hardening
ndyakov Aug 6, 2026
7859a4c
fix(multidb): manual-selection consistency from final sweep
ndyakov Aug 6, 2026
012c493
fix(multidb): construction and callback consistency sweep
ndyakov Aug 6, 2026
d2047c6
fix(multidb): shutdown, callback and aliasing consistency sweep
ndyakov Aug 6, 2026
ba91ba6
fix(multidb): close-race guards, probe neutrality and strategy recovery
ndyakov Aug 6, 2026
68c5612
fix(multidb): match HIMPORT by name too, classify rejection neutral
ndyakov Aug 6, 2026
4929860
fix(multidb): classify typed server replies as reply outcomes
ndyakov Aug 7, 2026
344fdaf
fix(multidb): settle command outcomes by admission reservation
ndyakov Aug 7, 2026
7566dc0
docs(multidb): note hook scope of cluster-wide delegates
ndyakov Aug 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,43 @@ func NewTestSentinelFailover(opt *FailoverOptions, sentinelAddrs []string) *sent
func (c *sentinelFailover) ReplicaAddrs(ctx context.Context) ([]string, error) {
return c.replicaAddrs(ctx, false)
}

// TestBreakerRecordFailure records one failure on the indexed member's
// circuit breaker. Exported for testing breaker-gate interactions.
func (c *MultiDBClient) TestBreakerRecordFailure(index int) {
c.core.dbAt(index).cb.RecordFailure()
}

// TestBreakerReserveHalfOpen runs the indexed member's breaker admission
// check, reserving one half-open probe slot when the breaker is half-open.
// Exported for testing breaker-gate interactions.
func (c *MultiDBClient) TestBreakerReserveHalfOpen(index int) bool {
return c.core.dbAt(index).cb.IsAllowed()
}

// TestProbeRacingRemoval reproduces the background health-check loop racing a
// concurrent RemoveDatabase: the member is snapshotted (as the loop does),
// removed, and then probed through the stale snapshot.
func (c *MultiDBClient) TestProbeRacingRemoval(index int) {
db := c.core.dbAt(index)
if err := c.core.removeDatabase(context.Background(), index); err != nil {
panic(err)
}
db.probe(context.Background(), c.core.opts.HealthCheckTimeout)
}

// TestRunHealthChecksOnce runs one synchronous background health-check pass.
func (c *MultiDBClient) TestRunHealthChecksOnce() {
c.core.runHealthChecksOnce(context.Background())
}

// TestStaleRecordAfterRemoval simulates a probe that passed its removed-check
// just before the member was removed: the breaker outcome lands after the
// removal completed.
func (c *MultiDBClient) TestStaleRecordAfterRemoval(index int) {
db := c.core.dbAt(index)
if err := c.core.removeDatabase(context.Background(), index); err != nil {
panic(err)
}
db.cb.RecordFailure()
}
Loading
Loading