您的位置:首页 > 编程语言 > Go语言

mgo 驱动新加重连

2015-06-04 10:47 447 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: