Skip to content

Commit c51b9c4

Browse files
authored
pkg/services: wrap context to prevent mockery race (#1988)
1 parent cd522c5 commit c51b9c4

3 files changed

Lines changed: 59 additions & 13 deletions

File tree

pkg/services/stop.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,3 @@ func (s StopRChan) Ctx(ctx context.Context) (context.Context, context.CancelFunc
4848
func (s StopRChan) CtxWithTimeout(timeout time.Duration) (context.Context, context.CancelFunc) {
4949
return s.CtxCancel(context.WithTimeout(context.Background(), timeout))
5050
}
51-
52-
// CtxCancel cancels a [context.Context] when StopChan is closed.
53-
// Returns ctx and cancel unmodified, for convenience.
54-
func (s StopRChan) CtxCancel(ctx context.Context, cancel context.CancelFunc) (context.Context, context.CancelFunc) {
55-
go func() {
56-
select {
57-
case <-s:
58-
cancel()
59-
case <-ctx.Done():
60-
}
61-
}()
62-
return ctx, cancel
63-
}

pkg/services/stop_!race.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//go:build !race
2+
3+
package services
4+
5+
import "context"
6+
7+
// CtxCancel cancels a [context.Context] when StopChan is closed.
8+
// Returns ctx and cancel unmodified, for convenience.
9+
func (s StopRChan) CtxCancel(ctx context.Context, cancel context.CancelFunc) (context.Context, context.CancelFunc) {
10+
go func() {
11+
select {
12+
case <-s:
13+
cancel()
14+
case <-ctx.Done():
15+
}
16+
}()
17+
return ctx, cancel
18+
}

pkg/services/stop_race.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//go:build race
2+
3+
package services
4+
5+
import (
6+
"context"
7+
"time"
8+
)
9+
10+
// CtxCancel cancels a [context.Context] when StopChan is closed.
11+
// Returns ctx and cancel unmodified, for convenience.
12+
func (s StopRChan) CtxCancel(ctx context.Context, cancel context.CancelFunc) (context.Context, context.CancelFunc) {
13+
go func() {
14+
select {
15+
case <-s:
16+
cancel()
17+
case <-ctx.Done():
18+
}
19+
}()
20+
return &syncCtx{
21+
deadline: ctx.Deadline,
22+
done: ctx.Done,
23+
value: ctx.Value,
24+
err: ctx.Err,
25+
}, cancel
26+
}
27+
28+
var _ context.Context = &syncCtx{}
29+
30+
// syncCtx is a context.Context implementation that is safe to format via %#v, which mockery uses.
31+
type syncCtx struct {
32+
deadline func() (time.Time, bool)
33+
done func() <-chan struct{}
34+
value func(any) any
35+
err func() error
36+
}
37+
38+
func (s *syncCtx) Deadline() (time.Time, bool) { return s.deadline() }
39+
func (s *syncCtx) Done() <-chan struct{} { return s.done() }
40+
func (s *syncCtx) Value(k any) any { return s.value(k) }
41+
func (c *syncCtx) Err() error { return c.err() }

0 commit comments

Comments
 (0)