【问题标题】:Should there be a new datastore.Client per HTTP request?每个 HTTP 请求都应该有一个新的 datastore.Client 吗?
【发布时间】:2020-05-05 23:23:40
【问题描述】:

official Go documentation on the datastore package(GCP 数据存储服务的客户端库)具有以下代码 sn-p 用于演示:

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 新手,真的找不到任何在线资源可以通过真实世界的示例和实际的最佳实践模式很好地解释此类问题。

【问题讨论】:

    标签: go google-cloud-platform google-cloud-datastore


    【解决方案1】:

    您可以使用任何context.Context 来创建数据存储客户端,它可能是context.Background(),完全可以。客户端创建可能很长,可能需要连接到远程服务器、身份验证、获取配置等。如果您的用例时间有限,您可以传递一个带有超时的上下文来中止操作。此外,如果创建时间比您拥有的时间长,您可以使用带有取消的上下文并随意中止任务。这些只是您可能会或可能不会使用的选项。但是“工具”是通过context.Context 提供的。

    稍后当您在服务 (HTTP) 客户端请求期间使用 datastore.Client 时,使用请求的上下文是合理的,因此如果请求被取消,那么它的上下文也会如此,您发出的数据存储操作也会如此,这是正确的,因为如果客户端看不到结果,那么完成查询就没有意义了。提前终止查询可能不会使用某些资源(例如数据存储读取),并且可能会降低服务器的负载(通过中止其结果不会发送回客户端的作业)。

    【讨论】:

    • 太棒了,这就是我的想法,但我只是想知道为什么客户端创建甚至需要一个上下文对象开始?如果你能解释一下为什么context.Background() 在这种情况下是可以接受的,那将不胜感激!
    • 很好的答案,这完全有道理。感谢您今天第二次帮助我:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2017-01-20
    • 2012-01-07
    相关资源
    最近更新 更多