Skip to content

Commit cdcf76d

Browse files
craig[bot]dt
andcommitted
Merge #156102
156102: sql/colfetcher: make Pace() call conditional r=dt a=dt Previously we relied on the nil-safe Pace() call being a no-op when called on nil a Pacer to make pacing conditional on the txn priority as that priority was used to decide to set Pacer to a non-nil value or not. However Pace() is free to elect to perform some form of pacing even when called on a nil Pacer (e.g. by delegating to the runtime or some global state) so the cFetcher should explicitly choose to call Pace() or not call it based on whether or not it wants to be paced, instead of relying on the behavior of Pace to change. This (lack of) contract when calling Pace() is now made explicit in the doc comment on Pace(). Release note: none. Epic: none. Co-authored-by: David Taylor <[email protected]>
2 parents 901677f + 1ca7502 commit cdcf76d

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

pkg/sql/colfetcher/cfetcher.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,8 +751,14 @@ func (cf *cFetcher) setNextKV(kv roachpb.KeyValue) {
751751
// rows, the Batch.Length is 0.
752752
func (cf *cFetcher) NextBatch(ctx context.Context) (coldata.Batch, error) {
753753
for {
754-
if err := cf.pacer.Pace(ctx); err != nil {
755-
return nil, err
754+
// While Pace() is nil-safe, its contract does not require it be a total
755+
// no-op when nil. We, however, are using its nil-ness specifically to
756+
// reflect our prior determination of the scan's priority, so this call to
757+
// Pace() should be explicitly conditional on Pacer's non-nilness.
758+
if cf.pacer != nil {
759+
if err := cf.pacer.Pace(ctx); err != nil {
760+
return nil, err
761+
}
756762
}
757763
if debugState {
758764
log.Dev.Infof(ctx, "State %s", cf.machine.state[0])

pkg/util/admission/pacer.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@ type Pacer struct {
2323
cur *ElasticCPUWorkHandle
2424
}
2525

26-
// Pace will block as needed to pace work that calls it as configured. It is
27-
// intended to be called in a tight loop, and will attempt to minimize per-call
28-
// overhead. Non-nil errors are returned only if the context is canceled.
26+
// Pace will block as needed to pace work that calls it. It is intended to be
27+
// called in a tight loop, and will attempt to minimize per-call overhead.
28+
// Non-nil errors are returned only if the context is canceled.
29+
//
30+
// It is safe to call Pace() on a nil *Pacer, but it should not be assumed that
31+
// such a call will always be a no-op: Pace may elect to perform pacing any time
32+
// it is called, even if the *Pacer on which it is called is nil e.g. by
33+
// delegating to the Go runtime or other some global pacing.
2934
func (p *Pacer) Pace(ctx context.Context) error {
3035
if p == nil {
3136
return nil

0 commit comments

Comments
 (0)