3 回答

TA貢獻1804條經(jīng)驗 獲得超8個贊
我建議不要使用這樣的全局會話。相反,您可以創(chuàng)建一個負責(zé)所有數(shù)據(jù)庫交互的類型。例如:
type DataStore struct {
session *mgo.Session
}
func (ds *DataStore) ucol() *mgo.Collection { ... }
func (ds *DataStore) UserExist(user string) bool { ... }
這種設(shè)計有很多好處。一個重要的是,它允許您同時進行多個會話,因此,例如,如果您有一個 http 處理程序,您可以創(chuàng)建一個本地會話,該會話由一個獨立會話支持,僅用于該請求:
func (s *WebSite) dataStore() *DataStore {
return &DataStore{s.session.Copy()}
}
func (s *WebSite) HandleRequest(...) {
ds := s.dataStore()
defer ds.Close()
...
}
在這種情況下,mgo 驅(qū)動程序表現(xiàn)良好,因為會話在內(nèi)部緩存和重用/維護。每個會話在使用時也將由一個獨立的套接字支持,并且可以配置獨立的設(shè)置,并且還將具有獨立的錯誤處理。如果您使用單個全局會話,這些是您最終必須處理的問題。

TA貢獻1828條經(jīng)驗 獲得超3個贊
在 go 1.7 中,在 web 服務(wù)器上處理 mongo 會話的最慣用的方法是使用新的標(biāo)準庫包context編寫一個中間件,該中間件可以在defer session.Close()調(diào)用請求上下文 Done() 時附加到。所以你不需要記得關(guān)閉
AttachDeviceCollection = func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
db, err := infra.Cloner()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
collection, err := NewDeviceCollection(db)
if err != nil {
db.Session.Close()
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
ctx := context.WithValue(r.Context(), DeviceRepoKey, collection)
go func() {
select {
case <-ctx.Done():
collection.Session.Close()
}
}()
next.ServeHTTP(w, r.WithContext(ctx))
})
}
- 3 回答
- 0 關(guān)注
- 214 瀏覽
添加回答
舉報