使用上下文重用父上下文.是否有超时

  • 本文关键字:上下文 超时 是否 go
  • 更新时间 :
  • 英文 :


使用上下文重用父上下文。带新超时的WithTimeout

嗨,我是go的新手。我想知道是否可以重用父上下文来创建多个上下文。withTimeout((。原理是我必须按顺序调用多个网络请求,并希望使用父上下文同时为每个请求设置超时。

基本原理

当父对象的上下文被取消时,所有请求也将被取消。

问题

在下面的代码中,它显示了一个示例,其中LongProcess是网络请求。然而,在可以用context deadline exceeded进行第二个LongProcess调用之前,上下文是关闭的。

文件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
}

它看起来像是对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)
}

最新更新