通过新的超时对context.WithTimeout重用父上下文
你好,我是新来go的。我想知道是否可以重用父上下文来创建多个context.withTimeout()。其基本原理是,我必须按顺序调用多个网络请求,并希望使用父请求的上下文同时为每个请求设置超时。
基本原理
当父进程的上下文被取消时,发出的所有请求也将被取消。
问题
在下面的代码中,它显示了一个示例,其中LongProcess是网络请求。但是,在使用context deadline exceeded进行第二个LongProcess调用之前,上下文将被关闭。
documentation 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
}发布于 2020-04-17 18:30:26
它看起来像是对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)
}https://stackoverflow.com/questions/61269264
复制相似问题