了解上下文超时Golang

Lee*_*esa 10 go mongodb

我在理解如何检查上下文是否超出超时设置的截止日期时遇到麻烦,或者我是否应该检查所有内容?

这是mongo-go-driver的片段:

client, err := NewClient("mongodb://foo:bar@localhost:27017")
if err != nil { return err }
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil { return err }
Run Code Online (Sandbox Code Playgroud)

阅读此代码,我如何知道上下文是否超过了期限?从我天真的理解(或不理解)的角度来看,该行err = client.Connect(ctx)会给我错误,包括超过了截止日期(如果超过了),因此我认为我什至不需要显式检查?

但是,然后在四处浏览互联网以更好地了解上下文如何工作时,我遇到了一些选择情况的用法,这些情况明确地检查了以下情况(来自http://p.agnihotry.com/post/understanding_the_context_package_in_golang/的代码段):

//Use a select statement to exit out if context expires
  select {
  case <-ctx.Done():
    fmt.Println("sleepRandomContext: Time to return")
  case sleeptime := <-sleeptimeChan:
    //This case is selected when processing finishes before the context is cancelled
    fmt.Println("Slept for ", sleeptime, "ms")
  }
Run Code Online (Sandbox Code Playgroud)

我应该明确检查吗?如果没有,我什么时候应该使用显式检查?感谢您的时间和帮助!

sbe*_*rry 11

select你的问题的第二部分代码的代码有什么Connect方法可能看起来像。在那里检查是否ctx.Done()准备好发送。如果是,则上下文因超时发生或被cancel()调用而被取消。

错误是值。像这样对待他们。如果了解错误的原因(网络关闭?意外数据?超时?)对您来说很重要,那么您应该进行检查并采取相应措施。如果不管原因如何从错误中恢复都是相同的,那么检查错误就没有那么重要了。

  • @Leesa 关闭,但不完全。您最终还得到了 `cancel` 函数,您可以调用该函数,并且驱动程序 ** 应该但不需要遵守该函数**。但是查看代码,您可以看到至少有一个地方会检查取消/超时的上下文。 (2认同)

poy*_*poy 10

Acontext最适合用于管理某事物的生命周期。因此,如果您正在做某事(例如,处理文件),那么您应该检查上下文以确保该进程尚未被处理。

有两种方法可以检查 acontext是否已取消或超时:

  1. Context.Done() - 这将返回一个将在上下文取消时关闭的通道。
  2. Context.Err() - 如果上下文被取消,这将返回一个错误。

选择最适合您需求的一种。如果您正在使用渠道做事,那么使用context.Done()in aselect效果很好。如果您for在阅读 时使用循环io.Reader,则检查context.Err()会更容易。

话虽如此,如果你开始的东西也需要上下文,你应该总是使用你已经拥有的上下文,如果你希望在你被取消时取消那个新“事物”。