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
原文解释:
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
相关文章推荐
- Google收购传感器公司Lumedyne
- mongo与hbase区别
- django 自带过滤器
- 百度地图经纬度 转换到 腾讯地图/Google地图 对应经纬度
- google pay 支付踩过的坑
- go 语言资料参考
- go学习笔记:2.变量、类型、常量
- Go语言3-程序控制
- 拟牛顿法/Quasi-Newton,DFP算法/Davidon-Fletcher-Powell,及BFGS算法/Broyden-Fletcher-Goldfarb-Shanno
- OC基础学习——Block语法的学习和Category与Extension的初步认识
- Django. No changes detected when "makemigrations"
- golang web开发获取get、post、cookie参数
- Django学习(六) 模板
- golang学习(二)
- gRPC的简单Go例子
- 解决RelativeLayout中 gone之后的布局错位问题。RelativeLayout的alignWithParentIfMissing
- hdoj2151简单的计数DP
- 关于GoogleMap的使用经验
- go安装
- HDOJ2059简化记录条件找出问题本质DP