上下文
概述
MongoDB Go 驱动程序使用 Go 标准库中的context 包 允许应用程序为任何 阻塞方法 调用发出超时和取消的信号。阻塞方法依赖于外部事件,如网络输入或输出,以继续执行其任务。
Go 驱动程序中阻塞方法的示例是Insert()
方法。如果您想在 10 秒内对 Collection
执行插入操作,您可以使用带有超时的 Context。如果操作在超时时间内未完成,则方法返回错误。
client := mongo.Connect(context.TODO()) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client.Database("<db>").Collection("<collection>").Insert(ctx, bson.D{{"x",1}})
如果传递给操作的 Context 没有截止日期,您可以在您的 Client
上设置一个 Timeout
选项,操作将从这个设置中获取超时规范。有关使用单个超时设置的更多信息,请参阅连接指南.
过期时间
当操作超时或被取消时,驱动程序认为上下文已过期。驱动程序使用 Done()
方法检查上下文过期。
以下部分描述了驱动程序何时以及如何检查过期。
服务器选择
如果无法为操作选择服务器,驱动程序可能会阻塞方法调用。
在这种情况下,驱动程序会循环直到找到可用于操作的服务器。在每次迭代后,如果上下文已过期或选择过程超过 serverSelectionTimeoutMS
设置的时间,驱动程序将返回服务器选择超时错误。
有关驱动程序如何选择服务器的更多信息,请参阅服务器选择算法。
连接检查
如果没有可用的连接进行检查,驱动程序可能会阻塞方法调用。
选择服务器后,驱动程序尝试从服务器连接池中检查出一个连接。如果在检查连接时上下文已过期,方法将返回超时错误。
连接建立
如果驱动程序必须创建新的连接,则可能会阻塞方法调用。
当驱动程序创建新连接以执行操作时,上下文为建立过程设置超时。驱动程序将超时设置为上下文过期时间或连接超时时间,取较短者。
以下示例将连接超时设置为1秒,将上下文截止时间设置为2秒。由于连接超时时间较短,建立过程在1秒后过期。
opts := options.Client() opts.SetConnectTimeout(1*time.Second) client := mongo.Connect(context.TODO(), opts) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() client.Database("<db>").Collection("<collection>").InsertOne(ctx, bson.D{{"x",1}})
套接字读取和写入
当驱动程序检索连接以执行操作时,它将套接字的读取或写入截止时间设置为上下文截止时间或套接字超时时间,取较短者。
如果在执行Read()
或Write()
方法之后但在其截止时间之前取消上下文,则驱动程序的行为取决于版本。
当Read()
或Write()
方法正在进行时,驱动程序生成一个单独的goroutine来监听上下文取消。如果goroutine检测到取消操作,它将关闭连接。挂起的Read()
或Write()
方法返回一个错误,驱动程序将使用context.Canceled
错误覆盖它。
重要
在1.5.0之前的版本中,驱动程序不会检测上下文取消,并等待Read()
或Write()
方法返回。