英文:
Best Practise opening DB
问题
注意:我不确定这是否是这篇文章的最准确的标题,如果不是,请提供一个更好的标题。
目前,我正在创建一个服务器,其中包含几个处理程序(使用goji)。在接收到请求后,我想要与我拥有的MongoDB数据库进行交互(使用mgo)。我的问题是:
我假设每次处理请求时执行这种操作是昂贵的:
uri := os.Getenv("MONGOHQ_URL")
if uri == "" {
panic("no DB connection string provided")
}
session, err := mgo.Dial(uri)
那么,对我来说,是否更好的做法是拥有一个可以从处理程序内部访问的全局变量呢? 所以我会这样做:
var session *mgo.Session
func main() {
session = setupDB()
defer session.Close()
goji.Get("/user", getUser)
goji.Serve()
}
func getUser(c web.C, w http.ResponseWriter, r *http.Request) {
// 在这里使用 session 变量
}
我的问题与在这里应该采用什么最佳实践有关?是每次请求到来时打开数据库,还是在整个应用程序的生命周期内保持数据库连接打开?
英文:
Note: I am not sure if this is the most accurate title for this post, if not, please advise on a better one.
Currently I am creating a server where I have a couple of handlers (using goji). After receiving a request, I want to interact with a MongoDB database I have (using mgo). My question is:
I am assuming doing this kind of stuff every time I am handling a request is expensive:
uri := os.Getenv("MONGOHQ_URL")
if uri == "" {
panic("no DB connection string provided")
}
session, err := mgo.Dial(uri)
So, would it be better for me to have a global var that I can access from inside the handlers? So I would go with something like this:
var session *mgo.Session
func main() {
session = setupDB()
defer session.Close()
goji.Get("/user", getUser)
goji.Serve()
}
func getUser(c web.C, w http.ResponseWriter, r *http.Request) {
// Use the session var here
}
My question is related to what would be the best practise here? Opening the DB every time a request comes in, or keep it open for the entire duration of the application.
答案1
得分: 1
你可以像这样将你的处理程序包装在一个Controller结构体中:(http://play.golang.org/p/NK6GO_lqgk)
package main
import (
"fmt"
"log"
"net/http"
"os"
"github.com/zenazn/goji"
"github.com/zenazn/goji/web"
)
type Controller struct {
session *Session
}
func NewController() (*Controller, error) {
if uri := os.Getenv("MONGOHQ_URL"); uri == "" {
return nil, fmt.Errorf("no DB connection string provided")
}
session, err := mgo.Dial(uri)
if err != nil {
return nil, err
}
return &Controller{
session: session,
}, nil
}
func (c *Controller) getUser(c web.C, w http.ResponseWriter, r *http.Request) {
// 在这里使用session变量
}
func main() {
ctl, err := NewController()
if err != nil {
log.Fatal(err)
}
defer ctl.session.Close()
goji.Get("/user", ctl.getUser)
goji.Serve()
}
这样,你可以将session嵌入到处理程序中,并添加任何其他你可能需要的数据。
<details>
<summary>英文:</summary>
What about wraping your handler in a Controller struct like this: (http://play.golang.org/p/NK6GO_lqgk)
package main
import (
"fmt"
"log"
"net/http"
"os"
"github.com/zenazn/goji"
"github.com/zenazn/goji/web"
)
type Controller struct {
session *Session
}
func NewController() (*Controller, error) {
if uri := os.Getenv("MONGOHQ_URL"); uri == "" {
return nil, fmt.Errorf("no DB connection string provided")
}
session, err := mgo.Dial(uri)
if err != nil {
return nil, err
}
return &Controller{
session: session,
}, nil
}
func (c *Controller) getUser(c web.C, w http.ResponseWriter, r *http.Request) {
// Use the session var here
}
func main() {
ctl, err := NewController()
if err != nil {
log.Fatal(err)
}
defer ctl.session.Close()
goji.Get("/user", ctl.getUser)
goji.Serve()
}
This way, you can embed your session in your handler and add any other data that you might need.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论