-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
增加上下文时限管理能力 #54
base: develop
Are you sure you want to change the base?
增加上下文时限管理能力 #54
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# contextx | ||
|
||
|
||
## usage | ||
|
||
```golang | ||
// only remove deadline value | ||
ctx = contextx.WithNoDeadline(ctx) | ||
|
||
// only remove cancel value | ||
ctx = contextx.WithNoCancel(ctx) | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package contextx | ||
|
||
import ( | ||
"context" | ||
"time" | ||
) | ||
|
||
type valueOnlyContext struct{ context.Context } | ||
|
||
func (valueOnlyContext) Deadline() (deadline time.Time, ok bool) { return } | ||
func (valueOnlyContext) Done() <-chan struct{} { return nil } | ||
func (valueOnlyContext) Err() error { return nil } | ||
|
||
//WithNoDeadline only remove deadline value | ||
func WithNoDeadline(ctx context.Context) context.Context { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里的注释是不是可以更详细点呢,描述下使用的情况,以免误用 |
||
return valueOnlyContext{ctx} | ||
} | ||
|
||
//WithNoCancel only remove cancel value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同上 |
||
func WithNoCancel(ctx context.Context) context.Context { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
deadline, ok := ctx.Deadline() | ||
if ok { | ||
var cancel context.CancelFunc | ||
ctx = WithNoDeadline(ctx) | ||
ctx, cancel = context.WithDeadline(ctx, deadline) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 直接 ctx, _ = context.WithDeadline(ctx, deadline) 是不是就行了? |
||
_ = cancel | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里是为了避免 linter 报错么 |
||
return ctx | ||
} | ||
return WithNoDeadline(ctx) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package contextx | ||
|
||
import ( | ||
"context" | ||
"github.com/stretchr/testify/assert" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以使用 goimports 排序下 |
||
"testing" | ||
"time" | ||
) | ||
|
||
type ctxtype string | ||
|
||
var k ctxtype = "k" | ||
|
||
func TestWithNoDeadline(t *testing.T) { | ||
type args struct { | ||
ctx context.Context | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
stub func(*testing.T, context.Context) | ||
}{ | ||
{ | ||
name: "value is correct", | ||
args: args{ | ||
context.WithValue(context.TODO(), k, "world"), | ||
}, | ||
stub: func(t *testing.T, ctx context.Context) { | ||
assert.Equal(t, ctx.Value(k).(string), "world") | ||
}, | ||
}, | ||
{ | ||
name: "nil Deadline()", | ||
args: args{ | ||
ctx: func() context.Context { | ||
ctx, cancel := context.WithTimeout(context.TODO(), time.Second) | ||
_ = cancel | ||
return ctx | ||
}(), | ||
}, | ||
stub: func(t *testing.T, ctx context.Context) { | ||
deadline, ok := ctx.Deadline() | ||
assert.Equal(t, deadline.IsZero(), true) | ||
assert.Equal(t, ok, false) | ||
|
||
}, | ||
}, | ||
{ | ||
name: "nil Done()", | ||
args: args{ | ||
ctx: func() context.Context { | ||
ctx, cancel := context.WithTimeout(context.TODO(), time.Microsecond) | ||
_ = cancel | ||
return ctx | ||
}(), | ||
}, | ||
stub: func(t *testing.T, ctx context.Context) { | ||
assert.Equal(t, ctx.Done(), ctx.Done()) | ||
}, | ||
}, | ||
{ | ||
name: "nil Err()", | ||
args: args{ | ||
ctx: func() context.Context { | ||
ctx, cancel := context.WithTimeout(context.TODO(), time.Second) | ||
cancel() | ||
return ctx | ||
}(), | ||
}, | ||
stub: func(t *testing.T, ctx context.Context) { | ||
assert.Equal(t, ctx.Err(), nil) | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
got := WithNoDeadline(tt.args.ctx) | ||
tt.stub(t, got) | ||
}) | ||
} | ||
} | ||
|
||
func TestWithNoCancel(t *testing.T) { | ||
type args struct { | ||
ctx context.Context | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
stub func(*testing.T, context.Context) | ||
}{ | ||
{ | ||
name: "value is correct", | ||
args: args{ | ||
context.WithValue(context.TODO(), k, "world"), | ||
}, | ||
stub: func(t *testing.T, ctx context.Context) { | ||
assert.Equal(t, ctx.Value(k).(string), "world") | ||
}, | ||
}, | ||
|
||
{ | ||
name: "new Deadline()", | ||
args: args{ | ||
ctx: func() context.Context { | ||
ctx, cancel := context.WithDeadline(context.TODO(), time.Date(2022, 1, 1, 1, 1, 1, 1, time.Local)) | ||
_ = cancel | ||
return ctx | ||
}(), | ||
}, | ||
stub: func(t *testing.T, ctx context.Context) { | ||
deadline, ok := ctx.Deadline() | ||
assert.Equal(t, ok, true) | ||
assert.Equal(t, deadline, time.Date(2022, 1, 1, 1, 1, 1, 1, time.Local)) | ||
}, | ||
}, | ||
|
||
{ | ||
name: "cancel withTimeout context", | ||
args: args{ | ||
ctx: func() context.Context { | ||
now := time.Now() | ||
ctx := context.WithValue(context.Background(), "t", now) | ||
ctx, cancel := context.WithDeadline(ctx, now.Add(1000*time.Microsecond)) | ||
go func() { | ||
time.Sleep(100 * time.Microsecond) | ||
cancel() | ||
}() | ||
return ctx | ||
}(), | ||
}, | ||
|
||
stub: func(t *testing.T, ctx context.Context) { | ||
<-ctx.Done() | ||
duration := time.Since(ctx.Value("t").(time.Time)) | ||
if ctx.Err() == context.Canceled { | ||
t.Error("context canceled") | ||
} | ||
if duration < 200*time.Microsecond { | ||
t.Error("timeout cancel ") | ||
} | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
got := WithNoCancel(tt.args.ctx) | ||
tt.stub(t, got) | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// WithNoDeadline only remove deadline value
在 // 后加个空格吧