Mongodb 理解Golang上下文超时
我很难理解如何检查上下文是否超过了超时设置的截止日期,或者是否应该检查 这是mongo go驱动程序的一个片段:Mongodb 理解Golang上下文超时,mongodb,go,Mongodb,Go,我很难理解如何检查上下文是否超过了超时设置的截止日期,或者是否应该检查 这是mongo go驱动程序的一个片段: 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.C
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 }
阅读此代码,我如何知道上下文是否超过了截止日期?根据我天真的理解(或不理解),行err=client.Connect(ctx)
将给我错误,包括超过截止日期(如果超过),因此我认为我甚至不需要显式检查
但是,在浏览互联网以更好地了解上下文是如何工作的过程中,我遇到了使用select cases显式检查上下文的情况,如下所示(代码片段):
//如果上下文过期,请使用select语句退出
挑选{
case问题第二部分中的select
代码是Connect
方法中的代码可能是什么样子。它正在检查ctx.Done()
是否已准备好发送。如果已准备好发送,则上下文被取消,原因可能是发生了超时,也可能是调用了cancel()
错误是值。将其视为值。如果理解错误原因(网络关闭?意外数据?超时?)对您很重要然后,您应该进行检查并采取相应的行动。如果从错误中恢复(无论原因如何)是相同的,那么检查错误就没有那么重要了。Acontext
最好用于管理某件事的生命周期。因此,如果您正在做某件事(例如,处理文件),那么您应该检查上下文,以确保进程未被处理
有两种方法可以检查上下文是否已被取消或超时:
Context.Done()
-这将返回一个在取消上下文时将关闭的频道
Context.Err()
-如果取消上下文,则返回错误
选择最适合您需要的一个。如果您使用频道进行操作,则在选择中使用上下文。完成()
效果良好。如果您在读取io.Reader
时使用for
循环,则检查上下文。Err()
更容易
话虽如此,如果你开始做一些同样需要背景的事情,如果你想要新的“东西”,你应该始终使用你已经拥有的背景如果您被取消,将被取消。您能验证我是否理解您的意思吗?因此,如果我使用像mongo-go-driver
这样的外包包,并且它们的函数接受上下文,我可以安全地假设它们将为我处理上下文?这意味着,如果超过超时时间,该函数将在某个地方运行只需返回一个错误(可能会说“超过了截止日期”).总而言之,我通常只担心err!=nil?@Leesa Close,但不是完全。您最终也会得到cancel
函数,您可以调用该函数,并且驾驶员应该但不需要遵守该函数。但是查看代码,您可以看到至少有一个地方他们会检查取消/超时的上下文。
//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")
}