英文:
Keep mongoDB client connected Golang
问题
这是您要翻译的内容:
我试图理解为什么我的MongoDB客户端会断开连接,尽管有全局范围的变量。有些事情我不明白。我认为,某种程度上,这与ConnectToDatabase()
函数有关。
如果我在ConnectToDatabase()
函数中尝试对数据库进行一些操作,它可以正常工作,但是使用另一个包时,它会返回Client disconnected
错误。
以下是项目的结构:
├── database
│ ├── connect.go
│ └── models
├── go.mod
├── go.sum
├── handlers
│ └── user.go
├── main.go
├── README.md
└── services
├── create-user.go
└── get-users.go
以下是代码:
func main() {
fmt.Println("Users Data service started")
err := DB.ConnectToDatabase()
if err != nil {
log.Fatal(err)
}
l := log.New(os.Stdout, "service-user-data - ", log.LstdFlags)
userH := handlers.User(l)
sMux := http.NewServeMux()
sMux.Handle("/", userH)
s := &http.Server{
Addr: ":9090",
Handler: sMux,
IdleTimeout: 120 * time.Second,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
}
go func() {
err := s.ListenAndServe()
if err != nil {
l.Fatal(err)
}
}()
sigChan := make(chan os.Signal)
signal.Notify(sigChan, os.Interrupt)
signal.Notify(sigChan, os.Kill)
// Wait for an available signal
// Then print the message into the channel
sig := <-sigChan
l.Println("Recieved terminated, gracefully shutdown", sig)
ctxTimeOut, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
s.Shutdown(ctxTimeOut)
}
const (
dbURI = "mongodb://localhost:27017"
)
// CtxDB represent the context fot the database
var CtxDB, cancel = context.WithTimeout(context.Background(), 10*time.Second)
// DBClient spread all over the application the mongoDB client
var DBClient, err = mongo.NewClient(options.Client().ApplyURI(dbURI))
// DB represent the service database
var DB = DBClient.Database("service-users-data")
// UserCollection represent the user collection
var UserCollection = DB.Collection("users")
// ConnectToDatabase function handle the connection to the connection o the database
// It will return either client and err
func ConnectToDatabase() (err error) {
err = DBClient.Connect(CtxDB)
if err != nil {
log.Fatal(err)
} else {
fmt.Println("Database's client connected")
}
err = DBClient.Ping(CtxDB, readpref.Primary())
if err != nil {
log.Fatal(err)
} else {
fmt.Println("Client pinged")
}
defer DBClient.Disconnect(CtxDB)
return err
}
type users = models.Users
// GetUsers function return a list of user
func GetUsers(resWriter http.ResponseWriter, req *http.Request) (u users) {
ctx := database.CtxDB
cursor, err := database.UserCollection.Find(ctx, bson.M{})
if err != nil {
log.Fatal(err)
}
if err = cursor.All(ctx, &u); err != nil {
log.Fatal(err)
}
return u
}
- 这个文件夹结构实际上是正确的吗?
- 为什么这个客户端一直断开连接?
英文:
I try to understand why my mongoDB client disconnect despite the global scope variable. There is something that i dont understand. I think, somehow, this is related the ConnectToDatabase()
function.
If i try to do some operation on the DB in the ConnectToDatabase()
function, it goes well but with another package, it keep return Client disconnected
error.
Here the structure of the project:
├── database
│ ├── connect.go
│ └── models
├── go.mod
├── go.sum
├── handlers
│ └── user.go
├── main.go
├── README.md
└── services
├── create-user.go
└── get-users.go
Here the code:
func main() {
fmt.Println("Users Data service started")
err := DB.ConnectToDatabase()
if err != nil {
log.Fatal(err)
}
l := log.New(os.Stdout, "service-user-data - ", log.LstdFlags)
userH := handlers.User(l)
sMux := http.NewServeMux()
sMux.Handle("/", userH)
s := &http.Server{
Addr: ":9090",
Handler: sMux,
IdleTimeout: 120 * time.Second,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
}
go func() {
err := s.ListenAndServe()
if err != nil {
l.Fatal(err)
}
}()
sigChan := make(chan os.Signal)
signal.Notify(sigChan, os.Interrupt)
signal.Notify(sigChan, os.Kill)
// Wait for an available signal
// Then print the message into the channel
sig := <-sigChan
l.Println("Recieved terminated, gracefully shutdown", sig)
ctxTimeOut, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
s.Shutdown(ctxTimeOut)
}
const (
dbURI = "mongodb://localhost:27017"
)
// CtxDB represent the context fot the database
var CtxDB, cancel = context.WithTimeout(context.Background(), 10*time.Second)
// DBClient spread all over the application the mongoDB client
var DBClient, err = mongo.NewClient(options.Client().ApplyURI(dbURI))
// DB represent the service database
var DB = DBClient.Database("service-users-data")
// UserCollection represent the user collection
var UserCollection = DB.Collection("users")
// ConnectToDatabase function handle the connection to the connection o the database
// It will return either client and err
func ConnectToDatabase() (err error) {
err = DBClient.Connect(CtxDB)
if err != nil {
log.Fatal(err)
} else {
fmt.Println("Database's client connected")
}
err = DBClient.Ping(CtxDB, readpref.Primary())
if err != nil {
log.Fatal(err)
} else {
fmt.Println("Client pinged")
}
defer DBClient.Disconnect(CtxDB)
return err
}
type users = models.Users
// GetUsers function return a list of user
func GetUsers(resWriter http.ResponseWriter, req *http.Request) (u users) {
ctx := database.CtxDB
cursor, err := database.UserCollection.Find(ctx, bson.M{})
if err != nil {
log.Fatal(err)
}
if err = cursor.All(ctx, &u); err != nil {
log.Fatal(err)
}
return u
}
- Is this folder structure actually correct ?
- Why this client keep disconnecting ?
答案1
得分: 1
延迟调用的参数会立即求值,但是函数调用直到包围函数返回时才执行。
当你设置一个defer
子句时,它会在定义它的函数结束后执行。
基本上,你的延迟数据库关闭操作会在ConnectToDatabase
函数执行后立即发生。
我的建议是你返回sql.DB
对象,并且只在应用程序自身终止时断开连接,可能是在s.Shutdown(ctxTimeOut)
这一行之后。
英文:
> The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.
When you set a defer
clause, this will execute after the function it was defined in ends.
Basically, your deferred database close is happening right after the ConnectToDatabase
function is executed.
My recommendation is that you return the sql.DB
object and you disconnect only when the application itself terminates, maybe after the line s.Shutdown(ctxTimeOut)
.
答案2
得分: 0
关于客户端断开连接的问题,那是我的错误。
我在ConnectToDatabase()
函数中返回了err
,我猜想这会停止函数的执行,而不是让客户端完成他的工作。
但如果有人有时间检查一下代码和结构,并给我一些关于实践的反馈,那将是非常好的,也会受到很高的赞赏
英文:
About the issue concerning the disconnection of the client, that was my bad.
I was returning err
in ConnectToDatabase()
function and my guess is that was stopping the execution of the function instead of letting the client do his job.
But if anybody have the time to check a bit the code and the structure to give me a feedback about the practices, that could be great and well appreciated
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论