Go Lang и Labix mgo — получение EOF после последующих запросов

У меня есть веб-процесс, похожий на

func main() {
    // mgo
    mongoDatabase, err := mgopath.Connect(envMongoPath)
    if err != nil {
        log.Fatal(err)
    }

    r := mux.NewRouter()
    // ....
    r.HandleFunc("/apps/{app:.+}", stuffHandler(mongoDatabase)).Methods("GET")
    http.Handle("/", r)

    listen := fmt.Sprintf("%s:%s", host, port)
    log.Fatal(http.ListenAndServe(listen, nil))
}

в то время как mgopath.Connect выглядит

func Connect(mongoPath string) (*mgo.Database, error) {
    dbConfig, err := url.Parse(mongoPath)
    if err != nil {
        return nil, err
    }

    log.Printf("Connecting to %s", dbConfig.Host)
    sess, err := mgo.Dial(dbConfig.Host)
    if err != nil {
        return nil, err
    }

    dbName := dbConfig.Path
    log.Printf("Using database %s", dbName)
    if len(dbName) < 2 {
        return nil, errors.New("No database name specified.")
    }

    dbName = dbConfig.Path[1:len(dbConfig.Path)]
    return sess.DB(dbName), err
}

Где-то по дороге:

c := database.C("stuff")
err = c.Find(bson.M{"id": id}).One(&item) // First ~1-2 minutes work as expected, then I receive EOFs
// c.Insert(), c.Update(), c.All()...

Проблема в том, что через пару минут все запросы к mongodb возвращают ошибку EOF. Я должен перезапустить процесс, чтобы все снова заработало. Были проблемы как на Mac, так и (чаще) на Windows. MongoDB работает внутри Docker, который, в свою очередь, работает внутри boot2docker. Произведена переадресация портов ВМ (поэтому запросы работают определенное время).

Требует ли mgo набирать номер каждый раз, когда я делаю запрос? Есть ли какой-то тайм-аут, о котором я не знаю?


person machete    schedule 06.05.2015    source источник


Ответы (2)


Ответ можно найти здесь: https://groups.google.com/forum/#!topic/mgo-users/XM0rc6p-V-8

Есть два простых способа избавиться от ошибки:

1) Вызовите Refresh для сеанса, что заставляет его отбросить (или вернуть в пул, если соединение хорошее) соединение, которое он удерживает, и выбрать новое, когда это необходимо.

2) Вместо использования одного сеанса используйте несколько, вызвав session.Copy, когда вам нужен новый сеанс, а затем вызовите session.Close, когда вы закончите с ним. Это также будет означать, что вы используете несколько подключений к базе данных, когда это необходимо.

person machete    schedule 14.05.2015
comment
даже это не работает. см. это: github.com/go-mgo/mgo/issues/473 - person Inanc Gumus; 01.08.2017
comment
@InancGumus, я не вижу связи между вашей проблемой и этим вопросом. - person mikezter; 09.04.2018
comment
@mikezter Последующие запросы получают EOF - person Inanc Gumus; 09.04.2018

session.Copy может создать много подключений к mongodb, в больших проектах у вас может быть открыто «слишком много файлов», поэтому вы можете попробовать это:

https://github.com/ti/mdb

это автоматически вызовет session.refresh, если ваше соединение нестабильно.

меньше соединений и меньше ошибок для политики повторных попыток.

person lee    schedule 31.05.2017
comment
Добро пожаловать в СО. Пожалуйста, прочтите это как ответить, чтобы получить качественный ответ. - person thewaywewere; 31.05.2017