2014-12-03 19 views
1

我正在尝试在我的Go应用中配置mongo。我正在使用Gin框架。我也用mongo的mgo V2驱动程序。我想连接到mongo作为一个中间件。下面是我的了:配置mongo与杜松子酒golang框架

func Run(cfg common.Config) error { 

doWorkResource := &DoWorkResource{db: dbmap} 

r := gin.New() 

r.Use(middleware.DB()) 


r.POST("/register", doWorkResource.Register) 
r.POST("/login", doWorkResource.Login) 

r.Run(cfg.SvcHost) 

return nil 
} 

这是DB函数:

func DB() gin.HandlerFunc { 
    session, err := mgo.Dial("localhost:27017") 
    if err != nil { 
     panic(err) 
    } 

    defer session.Close() 

    return func(c *gin.Context) { 
     s := session.Clone() 

     db := s.DB("testing").C("testData") 
     err = db.Insert(&Person{"Ale", "+55 53 8116 9639"}, 
      &Person{"Cla", "+55 53 8402 8510"}) 
     if err != nil { 
      log.Fatal(err) 
     } 

     c.Next() 
    } 
} 

type Person struct { 
    Name string 
    Phone string 
} 

,如果我直接从主功能运行时,执行插入,但如果它是从DB run()函数。实际上,我在DB()函数的return语句内进行了记录,并且没有执行任何内容。我有一种感觉,我需要调用它作为参数传递给我的终点之一,但是当我做,我得到

cannot use middleware.DB (type func() gin.HandlerFunc) as type gin.HandlerFunc in argument to r.RouterGroup.POST

回答

1

看起来像你的问题就在这里:

defer session.Close() 

什么当你注册中间件时,你确实在做的不是每次调用中间件都调用中间件,而是定义每次调用时要做的事情。首先运行一组初始命令。这将是这部分:

session, err := mgo.Dial("localhost:27017") 
    if err != nil { 
    panic(err) 
} 

defer session.Close() 

然后返回一组指令运行每次你的端点中的一个被击中的时候,这将是这一部分:

s := session.Clone() 

db := s.DB("testing").C("testData") 
err = db.Insert(&Person{"Ale", "+55 53 8116 9639"}, 
    &Person{"Cla", "+55 53 8402 8510"}) 
if err != nil { 
    log.Fatal(err) 
} 

c.Next() 

当你从返回中间件初始化程序,它激活defer声明。然后,当第一个电话进入并尝试运行您以HandlerFunc的形式返回的指令时,它将失败,因为它正在尝试使用的会话已关闭。

+0

啊有道理。谢谢@Verran。我最终创建了一个独立的函数来初始化数据库,并分别为每个端点进行交互。我不希望每当端点被击中时都要执行相同的数据库操作。除了日志记录之外,是否有中间件用于其他用途(您希望为每个端点执行相同的操作)? – dmonay 2014-12-04 01:44:25

+0

关于我的头顶,我会说认证,比如检查OAuth密钥,检查白名单上的IP等。如果您想创建初始数据库会话并通过中间件返回原始会话的副本对于每个单独的连接来保持数据库调用并发,只要您不关闭调用Copy()的初始会话,就可以这样做。我相信除了基于个人用例之外,还有更多的场景,但那只是我的头顶。 – Verran 2014-12-04 17:21:00

相关问题