每个 HTTP 请求都应该有一个新的 datastore.Client 吗?

数据存储包(GCP 数据存储服务的客户端库)的官方 Go 文档具有以下演示代码片段:


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 新手,真的找不到任何在线资源可以很好地用真实世界的例子和实际的最佳实践模式来解释这样的事情。


DIEA
浏览 107回答 1
1回答

慕码人8056858

您可以使用 anycontext.Context来创建数据存储客户端,它可能是context.Background(),这完全没问题。客户端创建可能很长,可能需要连接到远程服务器、身份验证、获取配置等。如果您的用例时间有限,您可以传递一个带有超时的上下文来中止操作。此外,如果创建时间比您拥有的时间长,您可以使用带有取消的上下文并随意中止任务。这些只是您可能会或可能不会使用的选项。但是“工具”是通过context.Context.稍后,当您使用datastore.Client服务期间(HTTP)客户端请求时,使用请求的上下文是合理的,因此,如果请求被取消,那么它的上下文也会如此,您发出的数据存储操作也会如此,这是正确的,因为如果客户端不能看到结果,那么完成查询就没有意义了。提前终止查询,您可能最终不会使用某些资源(例如数据存储读取),并且您可能会降低服务器的负载(通过中止其结果不会发送回客户端的作业)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go