mgo 驱动新加重连


mgo 驱动目前没有实现远端server挂掉后,(当远端的session挂掉其实底层已经做了重连的机制,但是没有通知上层的sesion.)更新当前的session。而致使当前的session不可以用。目前我们可以采取两种方式来更新。

原文解释:

yoou can do that, but you don't *have* to. One common pattern, for 
example when handling http requests, is to Copy [1] a master session, 
use the copied session for the duration of a request, and then Close 
it. The closing is also commonly done with defer, so the Close [2] is 
right after the Copy, ensuring it's properly taken care of. 

For other tasks, it's also fine to just use one master session for the 
whole application. 

If you intend the application to remain running when there are hard 
errors (disconnections, etc), please just remember to Refresh [3] the 
session at some point in the application loop, so that after mgo 
notifies you about them, the error can be put away and a new 
connection allocated for the session. In practice, this just means 
something along the lines of: 

    // Main application loop. 
    for { 
        session.Refresh() 
        select { 
        case ... 
        } 
    } 

assuming the application would be using such a structure for the main loop. 


> and what about collections (ex: 
> session.DB(" 127.0.0.1:1234"). C("collectionName")) 

> should I create then once, or should I recreate them every single time I'm 
> really reading or writing smth from/to mongo 

A Database [4] holds a Session field, and a Collection [5] holds a 
Database field, so w'hat was just explained above for a session 
applies to both given their association with one. 

1) Call Refresh on the session, which makes it discard (or put back in 

the pool, if the connection is good) the connection it's holding, and 
pick a new one when necessary. 

2) Instead of using a single session, use many by calling session.Copy 
when you need a new session, and then call session.Close when you're 

done with it. This will also mean you're using multiple connections to 

the database, when necessary.


实现方式:

采用单独的goroutines来管理session.关键代码:
if info.AutoReconnect {
session.stopMonitor = make(chan bool, 1)
go func() {
c := time.Tick(interval)
loop := true
for loop {
select {
case <-c:
if err := session.Ping(); err != nil && err == io.EOF {
session.Refresh()
} else {
}
case <-session.stopMonitor:
loop = false
break
}
}
}()
}


问题:

 I assume that calling Refresh() is also thread safe, that means I can call it in concurrent goroutines? 

That's not a good idea, as it will interfere with the other 
goroutines. In fact, that's the exact point of the error not being 
automatically reset: you don't want goroutines that are running to see 
a completely different server and state without any notice. They 
should all fail and go back to the start of your processing routine 
(loop, request handling, whatever) so you can move on again. 


附件是针对session.go做的修改。

参考:

https://groups.google.com/forum/#!topic/mgo-users/XM0rc6p-V-8


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值