Skip to content

Commit 66804bd

Browse files
authored
Merge pull request #1665 from ydb-platform/with-done
* Fixed bug in `internal/xcontext.WithDone` (not listening chan done)
2 parents e86522e + 15169e4 commit 66804bd

File tree

3 files changed

+39
-29
lines changed

3 files changed

+39
-29
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* Fixed bug in `internal/xcontext.WithDone` (not listening chan done)
2+
13
## v3.100.1
24
* Refactored behaviour on `retry.Retryable` error for retry object (such as session, connection or transaction)
35

internal/xcontext/done.go

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,25 @@ package xcontext
22

33
import (
44
"context"
5-
"time"
65
)
76

8-
type doneCtx <-chan struct{}
9-
10-
func (done doneCtx) Deadline() (deadline time.Time, ok bool) {
11-
return
12-
}
13-
14-
func (done doneCtx) Done() <-chan struct{} {
15-
return done
16-
}
17-
18-
func (done doneCtx) Err() error {
7+
func WithDone(parent context.Context, done <-chan struct{}) (context.Context, context.CancelFunc) {
8+
ctx, cancel := WithCancel(parent)
199
select {
2010
case <-done:
21-
return context.Canceled
11+
cancel()
12+
13+
return ctx, cancel
2214
default:
23-
return nil
2415
}
25-
}
2616

27-
func (done doneCtx) Value(key any) any {
28-
return nil
29-
}
17+
go func() {
18+
select {
19+
case <-done:
20+
cancel()
21+
case <-parent.Done():
22+
}
23+
}()
3024

31-
func WithDone(parent context.Context, done <-chan struct{}) (context.Context, context.CancelFunc) {
32-
ctx, cancel := context.WithCancel(parent)
33-
stop := context.AfterFunc(doneCtx(done), func() {
34-
cancel()
35-
})
36-
37-
return ctx, func() {
38-
stop()
39-
cancel()
40-
}
25+
return ctx, cancel
4126
}

internal/xcontext/done_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestWithDone(t *testing.T) {
1616
cancel()
1717
require.Error(t, ctx1.Err())
1818
})
19-
t.Run("CloseDone", func(t *testing.T) {
19+
t.Run("StopWithDone", func(t *testing.T) {
2020
ctx, cancel := context.WithCancel(context.Background())
2121
defer cancel()
2222
done := make(chan struct{})
@@ -26,4 +26,27 @@ func TestWithDone(t *testing.T) {
2626
require.NoError(t, ctx.Err())
2727
require.Error(t, ctx1.Err())
2828
})
29+
t.Run("CloseDone", func(t *testing.T) {
30+
done := make(chan struct{})
31+
ctx, cancel := WithDone(context.Background(), done)
32+
require.NoError(t, ctx.Err())
33+
close(done)
34+
<-ctx.Done()
35+
require.Error(t, ctx.Err())
36+
cancel()
37+
})
38+
t.Run("ClosedDone", func(t *testing.T) {
39+
done := make(chan struct{})
40+
close(done)
41+
ctx, cancel := WithDone(context.Background(), done)
42+
require.Error(t, ctx.Err())
43+
cancel()
44+
})
45+
t.Run("NilDone", func(t *testing.T) {
46+
var done chan struct{}
47+
ctx, cancel := WithDone(context.Background(), done)
48+
require.NoError(t, ctx.Err())
49+
cancel()
50+
require.Error(t, ctx.Err())
51+
})
2952
}

0 commit comments

Comments
 (0)