official Go documentation on the datastore package(GCP数据存储服务的客户端库)具有以下用于演示的代码段:
type Entity struct {
Value string
}
func main() {
ctx := context.Background()
// Create a datastore client. In a typical application, you would create
// a single client which is reused for every datastore operation.
dsClient, err := datastore.NewClient(ctx, "my-project")
if err != nil {
// Handle error.
}
k := datastore.NameKey("Entity", "stringID", nil)
e := new(Entity)
if err := dsClient.Get(ctx, k, e); err != nil {
// Handle error.
}
old := e.Value
e.Value = "Hello World!"
if _, err := dsClient.Put(ctx, k, e); err != nil {
// Handle error.
}
fmt.Printf("Updated value from %q to %q\n", old, e.Value)
}
正如人们所看到的,它指出datastore.Client
理想情况下应仅在应用程序中实例化一次。现在,假设datastore.NewClient
函数需要一个context.Context
对象,这是否意味着每个HTTP请求仅应实例化一次,还是可以安全地使用context.Background()
对象将其全局实例化一次?
每个操作再次需要一个context.Context
对象(例如dsClient.Get(ctx, k, e)
),因此应该使用HTTP请求的上下文?
我是Go的新手,无法真正找到任何在线资源,这些资源可以通过真实的示例和实际的最佳实践模式很好地解释这样的内容。
您可以使用任何context.Context
来创建数据存储区客户端,可能是context.Context
,这完全可以。客户端创建时间可能很长,可能需要连接到远程服务器,进行身份验证,获取配置等。如果您的用例时间有限,则可以传递带有超时的上下文来中止操作。同样,如果创建所花费的时间超过了您的创建时间,则可以使用带有cancel的上下文并随意放弃任务。这些只是您可能会使用或可能不会使用的选项。但是“工具”是通过context.Background()
给出的。
稍后在服务(HTTP)客户端请求期间使用context.Background()
时,则使用请求的上下文是合理的,因此,如果请求被取消,则其上下文也将被取消,您发出的数据存储区操作也将被正确处理,因为如果客户看不到结果,那么就没有必要完成查询。尽早终止查询,您可能不会最终使用某些资源(例如,数据存储读取),并且可能降低服务器的负载(通过中止其结果不会发送回客户端的作业)。