首頁 > 後端開發 > Golang > Golang cli 應用程式 - 如何正確使用上下文?

Golang cli 應用程式 - 如何正確使用上下文?

WBOY
發布: 2024-02-09 10:42:20
轉載
961 人瀏覽過

Golang cli 应用程序 - 如何正确使用上下文?

Golang cli 應用程式 - 如何正確使用上下文? php小編魚仔將為您介紹如何在Golang的cli應用程式中正確使用上下文。在開發cli應用程式時,上下文是非常重要的,它可以幫助我們管理應用程式的狀態、傳遞參數和錯誤等。本文將詳細解釋上下文的概念,並給出一些實際應用的範例,幫助您更好地理解和運用上下文。無論您是初學者還是有一定經驗的開發者,本文都將對您有所幫助。讓我們一起來深入了解Golang cli應用程式中的上下文吧!

問題內容

我是 golang 新手,對上下文以及如何在 golang 應用程式中使用上下文有些困惑。 具體來說,我正在開發 cli 應用程序,只需要訪問 mongo,例如。

就像 - 我只是創建單個共享 ctx 上下文變量,然後將其用於任何需要上下文的操作,這是正確的嗎?

任何需要上下文的操作都會重新啟動 5 秒計時器嗎?或者這是一個共享計時器?

package main

import (
    "context"
    "log"
    "os"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/mongo/readpref"
)

func main() {

    log.SetOutput(os.Stdout)

    // Create a context with a timeout of 5 seconds
    //This defines a timeout context that will be canceled after 5 seconds.
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    // always defer in case func returns early
    defer cancel()

    //Creates a new ClientOptions instance.
    clientOptions := options.Client()
    clientOptions = clientOptions.ApplyURI("mongodb+srv://127.0.0.1?retryWrites=true&w=majority")

    //Connect to mongo
    client, err := mongo.Connect(ctx, clientOptions)
    defer client.Disconnect(ctx)
    if err != nil {
        log.Fatal(err)
    }

    //Test connection to the database
    log.Println("I: test mongo connection using ping")
    err = client.Ping(ctx, readpref.Primary())
    if err != nil {
        log.Fatal(err)
    }

    log.Println("I: Fin")
}
登入後複製

解決方法

如果你仔細想想,context.context 可以「水平」共享(意思是在不屬於同一調用堆疊的操作之間)是沒有意義的。 golang context 提供了要執行操作(包括呼叫堆疊中其下方的任何巢狀操作)的上下文 - 例如“在 x 秒內”,以防止因通訊延遲等而掛起。因此,如果您發出並行 10 個請求,您應該為每個請求提供自己的上下文 - 您可能不希望第十個請求失敗,因為第一個請求失敗了。如果您只是使用context.background()context.todo(),沒有進一步的裝飾,您可能不需要在第一次建立它時將context 儲存在變數中- 您可以在建立時建立將其傳遞給呼叫堆疊中的第一個函數,正確建構的程式碼將根據需要將其向下傳遞到堆疊,並一路應用必要的修飾:

func Execute() {
  DoThing(context.Background())
  // Other stuff
}

func DoThing(pctx context.Context) {
  ctx, cancel := context.WithTimeout(pctx, 10 * time.Second) // Timeout after 10 seconds
  defer cancel()

  DoThingThatMayTakeAWhile(ctx)
  select {
    // You may want other stuff here
    case <-ctx.Done():
      // Context timed out, maybe log an error?
  }
}

func DoThingThatMayTakeAWhile(pctx context.Context) {
  DoThingNeedingInfoInContext(context.WithValue(pctx, "thisisakey", "value"))
}

func DoThingNeedingInfoInContext(ctx context.Context) {
  val := ctx.Value("thisisakey")
  // Do something with val, check that it isn't nil, etc.
}
  
登入後複製

如果我要多次呼叫dothingthatmaytakeawhile(),我想為每個呼叫提供一個單獨的子上下文- 我希望與每個呼叫共享ctx 。 p>

因此,在您的程式碼中,每次呼叫 mongo.connect() 都應該收到一個新建立的 context.context 實例。

以上是Golang cli 應用程式 - 如何正確使用上下文?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板