你好,我是新来的go
。我想知道是否可以重用父上下文来创建多个 context.withTimeout()。基本原理是我必须按顺序调用多个网络请求,并希望使用父级的上下文同时为每个请求设置超时。
当父的上下文被取消时,所有发出的请求也将被取消。
在下面的代码中,它显示了一个示例,LongProcess
即网络请求。但是,在LongProcess
可以使用 a 进行第二次调用之前,上下文已关闭context deadline exceeded
。
该文件withDeadline
指出The returned context's Done channel is closed when the deadline expires, when the returned cancel function is called, or when the parent context's Done channel isclosed, whichever happens first.
因此,如果是这种情况,有没有办法可以重置 withTimeout 的计时器?还是我必须context.Background()
为每个请求创建一个新的上下文?这意味着不会传递父上下文。:(
// LongProcess refers to a long network request
func LongProcess(ctx context.Context, duration time.Duration, msg string) error {
c1 := make(chan string, 1)
go func() {
// Simulate processing
time.Sleep(duration)
c1 <- msg
}()
select {
case m := <-c1:
fmt.Println(m)
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func main() {
ctx := context.Background()
t := 2 * time.Second
ctx, cancel := context.WithTimeout(ctx, t)
defer cancel()
// Simulate a 2 second process time
err := LongProcess(ctx, 2*time.Second, "first process")
fmt.Println(err)
// Reusing the context.
s, cancel := context.WithTimeout(ctx, t)
defer cancel()
// Simulate a 1 second process time
err = LongProcess(s, 1*time.Second, "second process")
fmt.Println(err) // context deadline exceeded
}
Run Code Online (Sandbox Code Playgroud)
看起来像是第一次调用context.WithTimeout
隐藏父上下文ctx
。后面的过程重新使用这个已经取消的上下文,因此出现错误。您必须重新使用父项。这是更新的示例:
func main() {
// Avoid to shadow child contexts
parent := context.Background()
t := 2 * time.Second
// Use the parent context.
ctx1, cancel := context.WithTimeout(parent, t)
defer cancel()
err := LongProcess(ctx1, 2*time.Second, "first process")
fmt.Println(err)
// Use the parent context not the canceled one.
ctx2, cancel := context.WithTimeout(parent, t)
defer cancel()
err = LongProcess(ctx2, 1*time.Second, "second process")
fmt.Println(err)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1415 次 |
最近记录: |