Skip to content

Commit

Permalink
added xcontext.WithDone() + replaced custom implementation `xcontex…
Browse files Browse the repository at this point in the history
…t.ValueOnly()` to standard `context.WithoutCancel()`
  • Loading branch information
asmyasnikov committed May 6, 2024
1 parent 7842cf9 commit 0f44d84
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
40 changes: 40 additions & 0 deletions internal/xcontext/done.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package xcontext

import (
"context"
"time"
)

type doneCtx <-chan struct{}

func (done doneCtx) Deadline() (deadline time.Time, ok bool) {

Check failure on line 10 in internal/xcontext/done.go

View workflow job for this annotation

GitHub Actions / golangci-lint

ST1016: methods on the same type should have the same receiver name (seen 1x "d", 3x "done") (stylecheck)
return
}

func (done doneCtx) Done() <-chan struct{} {
return done
}

func (done doneCtx) Err() error {
select {
case <-done:
return context.Canceled
default:
return nil
}
}

func (d doneCtx) Value(key any) any {

Check warning on line 27 in internal/xcontext/done.go

View workflow job for this annotation

GitHub Actions / golangci-lint

receiver-naming: receiver name d should be consistent with previous receiver name done for doneCtx (revive)
return nil
}

func WithDone(parent context.Context, done <-chan struct{}) (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(parent)
stop := context.AfterFunc(doneCtx(done), func() {
cancel()
})
return ctx, func() {

Check failure on line 36 in internal/xcontext/done.go

View workflow job for this annotation

GitHub Actions / golangci-lint

return with no blank line before (nlreturn)
stop()
cancel()
}
}
28 changes: 28 additions & 0 deletions internal/xcontext/done_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package xcontext

import (
"context"
"testing"

"github.com/stretchr/testify/require"
)

func TestWithDone(t *testing.T) {
t.Run("CancelParent", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
ctx1, _ := WithDone(ctx, done)
require.NoError(t, ctx1.Err())
cancel()
require.Error(t, ctx1.Err())
})
t.Run("CloseDone", func(t *testing.T) {
ctx, _ := context.WithCancel(context.Background())

Check failure on line 20 in internal/xcontext/done_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

lostcancel: the cancel function returned by context.WithCancel should be called, not discarded, to avoid a context leak (govet)
done := make(chan struct{})
ctx1, cancel1 := WithDone(ctx, done)
require.NoError(t, ctx1.Err())
cancel1()
require.NoError(t, ctx.Err())
require.Error(t, ctx1.Err())
})
}
13 changes: 1 addition & 12 deletions internal/xcontext/without_deadline.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,9 @@ package xcontext

import (
"context"
"time"
)

type valueOnlyContext struct {
context.Context //nolint:containedctx
}

func (valueOnlyContext) Deadline() (deadline time.Time, ok bool) { return }

func (valueOnlyContext) Done() <-chan struct{} { return nil }

func (valueOnlyContext) Err() error { return nil }

// ValueOnly helps to clear parent context from deadlines/cancels
func ValueOnly(ctx context.Context) context.Context {
return valueOnlyContext{ctx}
return context.WithoutCancel(ctx)
}

0 comments on commit 0f44d84

Please sign in to comment.