连接(localhost:27017 [-4])写入失败:上下文已取消

Den*_*boy 5 go mongodb

在这里我读到有必要取消上下文。这就是我的db.go样子:

package db

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

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

const (
    connectionStringTemplate = "mongodb://%s:%s@%s"
)

var DB *mongo.Client
var Ctx context.Context

// Connect with create the connection to MongoDB
func Connect() {
    username := os.Getenv("MONGODB_USERNAME")
    password := os.Getenv("MONGODB_PASSWORD")
    clusterEndpoint := os.Getenv("MONGODB_ENDPOINT")

    connectionURI := fmt.Sprintf(connectionStringTemplate, username, password, clusterEndpoint)

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    client, err := mongo.NewClient(options.Client().ApplyURI(connectionURI))
    if err != nil {
        log.Printf("Failed to create client: %v", err)
    }

    err = client.Connect(ctx)
    if err != nil {
        log.Printf("Failed to connect to cluster: %v", err)
    }

    // Force a connection to verify our connection string
    err = client.Ping(ctx, nil)
    if err != nil {
        log.Printf("Failed to ping cluster: %v", err)
    }

    DB = client
    Ctx = ctx
    log.Printf("Connected to MongoDB!")
}
Run Code Online (Sandbox Code Playgroud)

我在以下位置执行此操作main.go

func main() {

    // Configure
    db.Connect()
    defer db.DB.Disconnect(context.Background())

    r := gin.Default()

    // Routes
    //r.GET("/movies", handlers.GetAllMoviesHandler)
    r.POST("/movies", handlers.AddMovieHandler)

    // listen and serve on 0.0.0.0:8080
    r.Run()
}
Run Code Online (Sandbox Code Playgroud)

如果我的本地 mongodb 正在运行,它就可以正常工作。现在,当我像这样使用客户端时(我知道命名仍然很糟糕):

func AddMovie(movie *Movie) (primitive.ObjectID, error) {
    movie.ID = primitive.NewObjectID()
    result, err := db.DB.Database("movies").Collection("movies").InsertOne(db.Ctx, movie)
    if err != nil {
        log.Printf("Could not create movie: %v", err)
        return primitive.NilObjectID, err
    }
    oid := result.InsertedID.(primitive.ObjectID)
    return oid, nil
}
Run Code Online (Sandbox Code Playgroud)

我收到这样的错误

{"msg":{"Code":0,"Message":"connection(localhost:27017[-4]) failed to write: context canceled","Labels":["NetworkError","RetryableWriteError"],"Name":"","Wrapped":{"ConnectionID":"localhost:27017[-4]","Wrapped":{}}}}
Run Code Online (Sandbox Code Playgroud)

当我发表评论时它工作正常defer cancel(),但我认为这是不正确的?我在这里做错了什么。

更新:

result, err :=db.DB.Database("movies").Collection("movies").InsertOne(context.Background(), movie)当我使用:而不是 ctx 时它有效 。我不完全理解这些用例中上下文的用法。我也不确定是否应该Ctx = ctx在连接功能中执行此操作。