英文:
Go: client is disconnected
问题
我加入Gophers团队已经有几周了。到目前为止一切顺利。
我正在使用一个fiber网络框架来构建后端API。
我正在使用MongoDB作为我的数据库。
database/db.go
package database
import (
"context"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
var DB *mongo.Database
// InitMongo : 初始化mongodb...
func connectToMongo() {
log.Printf("初始化数据库")
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal("无法连接到数据库,原因:", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
err = client.Connect(ctx)
if err != nil {
log.Fatal("上下文错误,mongoDB:", err)
}
// 取消上下文以避免内存泄漏
defer cancel()
defer client.Disconnect(ctx)
// 检查数据库连接
err = client.Ping(context.Background(), readpref.Primary())
if err != nil {
log.Fatal("Ping, mongoDB:", err)
}
log.Printf("数据库已连接!")
// 创建一个数据库
DB = client.Database("golang-test")
return
}
// 在Golang中,init()函数在调用包时总是初始化。
// 因此,每当调用DB变量时,init()函数都会初始化
func init() {
connectToMongo()
}
controllers/mongo.controller/mongo.controller.go
package mongocontroller
import (
"log"
"github.com/gofiber/fiber/v2"
service "gitlab.com/.../services/mongoservice"
)
// GetPersons godoc
// @Summary 获取人员信息。
// @Description 获取人员信息
// @Tags persons
// @Produce json
// @Success 200 {object} []service.Person
// @Failure 400 {object} httputil.HTTPError
// @Failure 404 {object} httputil.HTTPError
// @Failure 500 {object} httputil.HTTPError
// @Router /v1/persons [get]
func GetPersons(c *fiber.Ctx) error {
res, err := service.GetPersons()
if err != nil {
log.Fatal("ERROR: 在控制器中...", err)
}
return c.JSON(res)
}
services/mongoservice/mongo.service.go
package mongoservice
import (
"context"
"log"
database "gitlab.com/.../database"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// Person : ...
type Person struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
Name string `bson:"name,omitempty" json:"name,omitempty"`
Age int `bson:"age,omitempty" json:"age,omitempty"`
}
func GetPersons() ([]Person, error) {
ctx := context.Background()
persons := []Person{}
log.Printf("mongo数据...", ctx)
cur, err := database.DB.Collection("persons").Find(ctx, bson.M{})
if err != nil {
log.Fatal(err)
}
// 遍历返回的游标。
for cur.Next(ctx) {
var person Person
cur.Decode(&person)
persons = append(persons, person)
}
defer cur.Close(ctx)
return persons, err
}
这是我存储在数据库中的数据:
问题是,服务中的**cur, err := database.DB.Collection("persons").Find(ctx, bson.M{})**这一行总是抛出Client is disconnected
的错误。
感谢您的帮助!
谢谢。
英文:
It's been few weeks since I joined in Gophers team. So far so good.
I started a new project using a fiber web framework to build backend APIs.
I am using MongoDB as my database.
database/db.go
package database
import (
"context"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
var DB *mongo.Database
// InitMongo : Initialize mongodb...
func connectToMongo() {
log.Printf("Initializing database")
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal("Could not able to connect to the database, Reason:", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
err = client.Connect(ctx)
if err != nil {
log.Fatal("Context error, mongoDB:", err)
}
//Cancel context to avoid memory leak
defer cancel()
defer client.Disconnect(ctx)
// Ping our db connection
err = client.Ping(context.Background(), readpref.Primary())
if err != nil {
log.Fatal("Ping, mongoDB:", err)
}
log.Printf("Database connected!")
// Create a database
DB = client.Database("golang-test")
return
}
// In Golang, init() functions always initialize whenever the package is called.
// So, whenever DB variable called, the init() function initialized
func init() {
connectToMongo()
}
controllers/mongo.controller/mongo.controller.go
package mongocontroller
import (
"log"
"github.com/gofiber/fiber/v2"
service "gitlab.com/.../services/mongoservice"
)
// GetPersons godoc
// @Summary Get persons.
// @Description Get persons
// @Tags persons
// @Produce json
// @Success 200 {object} []service.Person
// @Failure 400 {object} httputil.HTTPError
// @Failure 404 {object} httputil.HTTPError
// @Failure 500 {object} httputil.HTTPError
// @Router /v1/persons [get]
func GetPersons(c *fiber.Ctx) error {
res, err := service.GetPersons()
if err != nil {
log.Fatal("ERROR: in controller...", err)
}
return c.JSON(res)
}
services/mongoservice/mongo.service.go
package mongoservice
import (
"context"
"log"
database "gitlab.com/.../database"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// Person : ...
type Person struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
Name string `bson:"name,omitempty" json:"name,omitempty"`
Age int `bson:"age,omitempty" json:"age,omitempty"`
}
func GetPersons() ([]Person, error) {
ctx := context.Background()
persons := []Person{}
log.Printf("mongo data...", ctx)
cur, err := database.DB.Collection("persons").Find(ctx, bson.M{})
if err != nil {
log.Fatal(err)
}
// Iterate through the returned cursor.
for cur.Next(ctx) {
var person Person
cur.Decode(&person)
persons = append(persons, person)
}
defer cur.Close(ctx)
return persons, err
}
Here is my data stored in the database:
The problem is, the line cur, err := database.DB.Collection("persons").Find(ctx, bson.M{}) from service always throwing Client is disconnected
.
Any help is appreciated!
Thank you.
答案1
得分: 8
你正在同一个函数中调用defer client.Disconnect(ctx)
,而这个函数是用来创建连接的(connectToMongo
),所以在调用完函数后会关闭连接。你应该在完成任务后返回连接并关闭。我指的是这些部分:
defer cancel()
defer client.Disconnect(ctx)
英文:
You are calling defer client.Disconnect(ctx)
in the same function which is creating the connection (connectToMongo
) so it will close the connection after calling the function. You should return the connection and close after finishing your task. I mean these parts:
defer cancel()
defer client.Disconnect(ctx)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论