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").
>
> should I create then once, or should I recreate them every single time I'm
> really reading or writing smth from/to mongo
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, andpick 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
}
}
}()
}
问题:
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