Golang / MGO — 报错:没有可达的服务器

huangapple go评论118阅读模式
英文:

Golang / MGO -- panic: no reachable servers

问题

我有以下连接到Mongo的函数。为了测试,我关闭了mongod,并希望在没有Mongo可用时允许程序继续运行。似乎如果无法连接到服务器,MGO会引发panic,所以我写了一个defer/recover,但panic仍然导致程序退出。从这种情况中恢复的正确方法是什么?

  1. func connectToMongo(sess *mgo.Session, coll *mgo.Collection, sessionErr error) bool {
  2. fmt.Println("enter main - connecting to mongo")
  3. // 尝试这样做-不按预期工作
  4. defer func() {
  5. if r := recover(); r != nil {
  6. var ok bool
  7. err, ok := r.(error)
  8. if !ok {
  9. fmt.Printf("pkg: %v, error: %s", r, err)
  10. }
  11. }
  12. return false
  13. }()
  14. maxWait := time.Duration(5 * time.Second)
  15. sess, sessionErr = mgo.DialWithTimeout("localhost", maxWait)
  16. if sessionErr == nil {
  17. session.SetMode(mgo.Monotonic, true)
  18. coll = session.DB("MyDB").C("MyCollection")
  19. } else { // 永远不会执行到这里
  20. fmt.Println("无法连接到本地Mongo实例!")
  21. }
  22. return true
  23. }
英文:

I have the following function that connects to Mongo. For testing, I shutdown mongod, and want to allow the program to continue w/0 mongo if it's not available. It seems that MGO throws a panic if the server can't be connected, so I wrote a defer/recover below, but the panic still causes the program to exit. What's the proper way to recover from this?

  1. func connectToMongo(sess *mgo.Session, coll *mgo.Collection, sessionErr error) bool {
  2. fmt.Println("enter main - connecting to mongo")
  3. // tried doing this - doesn't work as intended
  4. defer func() {
  5. if r := recover(); r != nil {
  6. var ok bool
  7. err, ok := r.(error)
  8. if !ok {
  9. fmt.Printf("pkg: %v, error: %s", r, err)
  10. }
  11. }
  12. return false
  13. }()
  14. maxWait := time.Duration(5 * time.Second)
  15. sess, sessionErr = mgo.DialWithTimeout("localhost", maxWait)
  16. if sessionErr == nil {
  17. session.SetMode(mgo.Monotonic, true)
  18. coll = session.DB("MyDB").C("MyCollection")
  19. } else { // never gets here
  20. fmt.Println("Unable to connect to local mongo instance!")
  21. }
  22. return true
  23. }

答案1

得分: 4

请运行以下版本的代码:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. import (
  7. "labix.org/v2/mgo"
  8. )
  9. func connectToMongo() bool {
  10. ret := false
  11. fmt.Println("进入主函数 - 连接到MongoDB")
  12. // 尝试这样做 - 不按预期工作
  13. defer func() {
  14. if r := recover(); r != nil {
  15. fmt.Println("检测到恐慌")
  16. var ok bool
  17. err, ok := r.(error)
  18. if !ok {
  19. fmt.Printf("pkg: %v, 错误: %s", r, err)
  20. }
  21. }
  22. }()
  23. maxWait := time.Duration(5 * time.Second)
  24. session, sessionErr := mgo.DialWithTimeout("localhost:27017", maxWait)
  25. if sessionErr == nil {
  26. session.SetMode(mgo.Monotonic, true)
  27. coll := session.DB("MyDB").C("MyCollection")
  28. if coll != nil {
  29. fmt.Println("获得一个集合对象")
  30. ret = true
  31. }
  32. } else { // 永远不会执行到这里
  33. fmt.Println("无法连接到本地MongoDB实例!")
  34. }
  35. return ret
  36. }
  37. func main() {
  38. if connectToMongo() {
  39. fmt.Println("已连接")
  40. } else {
  41. fmt.Println("未连接")
  42. }
  43. }

当MongoDB运行时,你会看到:

  1. 进入主函数 - 连接到MongoDB
  2. 获得一个集合对象
  3. 已连接

当MongoDB关闭时,你会看到:

  1. 进入主函数 - 连接到MongoDB
  2. 无法连接到本地MongoDB实例!
  3. 未连接

如果你没有看到相同的行为,请发布输出,包括你看到的恐慌信息。

英文:

Run the following version of your posted code.
Try to not modify the code, at least not changing the position of the line numbers. That way, if you post a stacktrace, the numbers will match.

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. import (
  7. "labix.org/v2/mgo"
  8. )
  9. func connectToMongo() bool {
  10. ret := false
  11. fmt.Println("enter main - connecting to mongo")
  12. // tried doing this - doesn't work as intended
  13. defer func() {
  14. if r := recover(); r != nil {
  15. fmt.Println("Detected panic")
  16. var ok bool
  17. err, ok := r.(error)
  18. if !ok {
  19. fmt.Printf("pkg: %v, error: %s", r, err)
  20. }
  21. }
  22. }()
  23. maxWait := time.Duration(5 * time.Second)
  24. session, sessionErr := mgo.DialWithTimeout("localhost:27017", maxWait)
  25. if sessionErr == nil {
  26. session.SetMode(mgo.Monotonic, true)
  27. coll := session.DB("MyDB").C("MyCollection")
  28. if ( coll != nil ) {
  29. fmt.Println("Got a collection object")
  30. ret = true
  31. }
  32. } else { // never gets here
  33. fmt.Println("Unable to connect to local mongo instance!")
  34. }
  35. return ret
  36. }
  37. func main() {
  38. if ( connectToMongo() ) {
  39. fmt.Println("Connected")
  40. } else {
  41. fmt.Println("Not Connected")
  42. }
  43. }

When MongoDB is up, I see:

  1. enter main - connecting to mongo
  2. Got a collection object
  3. Connected

When MongoDB is down, I see:

  1. enter main - connecting to mongo
  2. Unable to connect to local mongo instance!
  3. Not Connected

If you don't see the same behavior, post the output, including the panic you see.

huangapple
  • 本文由 发表于 2014年1月7日 23:52:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/20976030.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定