为了账号安全,请及时绑定邮箱和手机立即绑定

重用 mongodb 连接时处理上下文

重用 mongodb 连接时处理上下文

Go
慕斯709654 2022-08-15 15:47:51
我通过作为参数传递来使多个 goroutine 共享单个连接。clienturi := "mongodb://localhost:27017"ctx := context.Background()client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))go Foo(client)go Bar(client)func Foo(client *mongo.Client) {        // ... }func Bar(client *mongoClient) {        // ...}我对如何处理感到困惑。我应该在每次查询数据库时都创建一个新上下文,还是应该像客户端一样重用上下文?ctx
查看完整描述

2 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

这取决于您的和方法的行为方式。让我们想象一下,该方法是一个简单的短命goroutine,它对DB进行一个查询,您唯一想要的就是检查其父上下文是否为“完成”或“取消”。然后,您可以为 Foo 方法提供父上下文。FooBarFoo


func main() {

    uri := "mongodb://localhost:27017"

    ctx := context.Background()

    client, err := Connect(ctx, uri)


    ctx, cancel := context.WithCancel(ctx)


    

    if err != nil {

        panic(err)

    }


    go Foo(ctx, client)

    go Bar(context.WithValue(ctx, "uri", uri), client)


    // cancel parent context

    cancel()


    time.Sleep(5*time.Second)

}


func Foo(ctx context.Context, client *Client) {

    fmt.Printf("Foo: %s\n", ctx.Value("uri"))

    select {

        case <- ctx.Done():

            err := ctx.Err()

            if err != nil {

                // you could switch for the actual reason

                fmt.Println("In our case context canceled: ", err)

                return

            }

            fmt.Printf("Do something...")

    }

}

另一方面,如果执行一些重要的逻辑并对 DB 进行多次调用,您可能希望一个单独的上下文能够将其与父上下文分开取消。然后,您可以从父母那里获得新的上下文。Bar


func Bar(ctx context.Context, client *Client) {

    // Bar has a non trivial logic and needs a separate cancellation and handling

    ctx, cancelFunc := context.WithCancel(ctx)

    fmt.Printf("Bar: %s\n", ctx.Value("uri"))

    

    // cancel derived context

    cancelFunc()


}


查看完整回答
反对 回复 2022-08-15
?
慕侠2389804

TA贡献1719条经验 获得超6个赞

我也这样做过


type DB struct {

    client *mongo.Client

}


func (db *DB) GetVideoStream {}


func main() {

    ctx, _ := context.WithTimeout(context.Background(), 60*time.Second)

    client, err := mongo.Connect(ctx, clientOpts)

    db := &DB{client: client}

    go db.GetVideoStream()

    http.HandleFunc("/api/", db.GetVideoStream)

}

您可以使用指针接收器来执行相同的操作。


我是新来的,还是该语言的新手


查看完整回答
反对 回复 2022-08-15
  • 2 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信