Skip to content

Commit a78e197

Browse files
craig[bot]erikgrinaker
andcommitted
119350: util/circuit: allow nil event handler r=erikgrinaker a=erikgrinaker Extracted from #118943. --- Users may not need an event handler, allow it to be unset. Epic: none Release note: None 119351: kvserver: add `Replica.GetMutexForTesting()` r=erikgrinaker a=erikgrinaker Extracted from #118943. --- This allows testing replica stalls and deadlocks from outside of the kvserver package. Epic: none Release note: None Co-authored-by: Erik Grinaker <[email protected]>
3 parents 66460bf + 4c94699 + 8f405f3 commit a78e197

File tree

8 files changed

+22
-11
lines changed

8 files changed

+22
-11
lines changed

pkg/jobs/joberror/errors_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ func TestErrBreakerOpenIsRetriable(t *testing.T) {
2525
AsyncProbe: func(_ func(error), done func()) {
2626
done() // never untrip
2727
},
28-
EventHandler: &circuit.EventLogger{Log: func(redact.StringBuilder) {}},
2928
})
3029
br.Report(errors.New("test error"))
3130
require.False(t, IsPermanentBulkJobError(br.Signal().Err()))

pkg/kv/kvserver/kvserverbase/stores.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type Store interface {
4242

4343
// GetReplicaMutexForTesting returns the mutex of the replica with the given
4444
// range ID, or nil if no replica was found. This is used for testing.
45+
// Returns a syncutil.RWMutex rather than ReplicaMutex to avoid import cycles.
4546
GetReplicaMutexForTesting(rangeID roachpb.RangeID) *syncutil.RWMutex
4647
}
4748

pkg/kv/kvserver/replica.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,3 +2464,8 @@ func (r *Replica) ReadProtectedTimestampsForTesting(ctx context.Context) (err er
24642464
ts, err = r.readProtectedTimestampsRLocked(ctx)
24652465
return err
24662466
}
2467+
2468+
// GetMutexForTesting returns the replica's mutex, for use in tests.
2469+
func (r *Replica) GetMutexForTesting() *ReplicaMutex {
2470+
return &r.mu.ReplicaMutex
2471+
}

pkg/kv/kvserver/stores_base.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (s *baseStore) SetQueueActive(active bool, queue string) error {
9999
func (s *baseStore) GetReplicaMutexForTesting(rangeID roachpb.RangeID) *syncutil.RWMutex {
100100
store := (*Store)(s)
101101
if repl := store.GetReplicaIfExists(rangeID); repl != nil {
102-
return (*syncutil.RWMutex)(&repl.mu.ReplicaMutex)
102+
return (*syncutil.RWMutex)(repl.GetMutexForTesting())
103103
}
104104
return nil
105105
}

pkg/rpc/peer.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,6 @@ func (rpcCtx *Context) newPeer(k peerKey) *peer {
185185
p.launch(ctx, report, done)
186186
})
187187
},
188-
// Use a noop EventHandler; we do our own logging in the probe since we'll
189-
// have better information.
190-
EventHandler: &circuit.EventLogger{Log: func(buf redact.StringBuilder) {}},
191188
})
192189
p.b = b
193190
c := newConnectionToNodeID(k, b.Signal)

pkg/util/circuit/circuitbreaker.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ func (b *Breaker) Report(err error) {
147147
}()
148148

149149
opts := b.Opts()
150-
opts.EventHandler.OnTrip(b, prevErr, storeErr)
150+
if opts.EventHandler != nil {
151+
opts.EventHandler.OnTrip(b, prevErr, storeErr)
152+
}
151153
if prevErr == nil {
152154
// If the breaker wasn't previously tripped, trigger the probe to give the
153155
// Breaker a shot at healing right away. If the breaker is already tripped,
@@ -163,7 +165,10 @@ func (b *Breaker) Report(err error) {
163165
// Outside of testing, there should be no reason to call this
164166
// as it is the probe's job to reset the breaker if appropriate.
165167
func (b *Breaker) Reset() {
166-
b.Opts().EventHandler.OnReset(b)
168+
opts := b.Opts()
169+
if opts.EventHandler != nil {
170+
opts.EventHandler.OnReset(b)
171+
}
167172
b.mu.Lock()
168173
defer b.mu.Unlock()
169174
// Avoid replacing errAndCh if it wasn't tripped. Otherwise,
@@ -255,7 +260,9 @@ func (b *Breaker) maybeTriggerProbe(force bool) {
255260
opts := *b.mu.Options // ok to leak out from under the lock
256261
b.mu.Unlock()
257262

258-
opts.EventHandler.OnProbeLaunched(b)
263+
if opts.EventHandler != nil {
264+
opts.EventHandler.OnProbeLaunched(b)
265+
}
259266
var once sync.Once
260267
opts.AsyncProbe(
261268
func(err error) {
@@ -269,7 +276,9 @@ func (b *Breaker) maybeTriggerProbe(force bool) {
269276
// Avoid potential problems when probe calls done() multiple times.
270277
// It shouldn't do that, but mistakes happen.
271278
once.Do(func() {
272-
opts.EventHandler.OnProbeDone(b)
279+
if opts.EventHandler != nil {
280+
opts.EventHandler.OnProbeDone(b)
281+
}
273282
b.mu.Lock()
274283
defer b.mu.Unlock()
275284
b.mu.probing = false

pkg/util/circuit/circuitbreaker_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ func BenchmarkBreaker_Signal(b *testing.B) {
438438
AsyncProbe: func(_ func(error), done func()) {
439439
done() // never untrip
440440
},
441-
EventHandler: &EventLogger{Log: func(redact.StringBuilder) {}},
442441
})
443442

444443
// The point of this benchmark is to verify the absence of allocations when

pkg/util/circuit/options.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ type Options struct {
4242
AsyncProbe func(report func(error), done func())
4343

4444
// EventHandler receives events from the Breaker. For an implementation that
45-
// performs unstructured logging, see EventLogger.
45+
// performs unstructured logging, see EventLogger. Can be nil if no event
46+
// handler is needed.
4647
EventHandler EventHandler
4748

4849
// signalInterceptor gets to see and change the return value of the Signal

0 commit comments

Comments
 (0)