mgo 驱动新加重连

来源:互联网 发布:彩票源码程序安装教程 编辑:程序博客网 时间:2024/05/01 18:49


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
原创粉丝点击