MongoError: курсор убит или истекло время ожидания - настройки тайм-аута Meteor неэффективны

Моя программа Meteor 1.2.1 выбрасывала MongoError: cursor killed or timed out в цикле find().forEach(), поэтому я нашел эта страница, в которой говорится, что этот код предотвращает следующее:

var myCursor = db.users.find().noCursorTimeout()

Однако в документах по драйверам и в моем Meteor указано, что такого метода не существует: Object [object Object] has no method 'noCursorTimeout'

Автоматическое переподключение Mongo включено по умолчанию и не помогло. форум Meteor или даже .find({}, {timeout:false}) согласно в этот комментарий.

2016-07-20 11:21:37 Началось обновление

20.07.2016, 11:37:21 Исключение при вызове метода updateCollections MongoError: курсор убит или истекло время ожидания

Может быть, Meteor запутался из-за неудачного вызова SOAP 20.07.2016 09:34:57?

  "error": {
    "errno": "ETIMEDOUT",
    "syscall": "connect",
    "code": "ETIMEDOUT"
  },

person Cees Timmerman    schedule 20.07.2016    source источник
comment
Как вы думаете, поможет ли метод maxTimeMS объекта курсора? Ты это пробовал?   -  person Tomasz Lenarcik    schedule 20.07.2016
comment
cursor.maxTimeMS(5000) приводит к Object [object Object] has no method 'maxTimeMS'. Сервер MongoDB 3.2 в Windows 10 понимает это, а Meteor 1.2.1 — нет. В файле версий указано [email protected], поэтому я попытаюсь его обновить.   -  person Cees Timmerman    schedule 20.07.2016
comment
Повторное добавление пакета mongo сохраняет версию Meteor [email protected].   -  person Cees Timmerman    schedule 20.07.2016


Ответы (1)


Предполагая, что maxTimeMS поможет в этом случае, вы можете получить к нему доступ, работая с объектом rawCollection вместо самой коллекции Meteor.

Это довольно просто:

var rawCollection = Meteor.users.rawCollection();
var cursor = rawCollection.find({}).maxTimeMS(5000);
var myData = fetchCursor(cursor);

Где fetchCursor — это простая вспомогательная функция с учетом оптоволокна, которую можно реализовать следующим образом:

var fetchCursor = Meteor.wrapAsync(function fetchCursor (cursor, cb) {
  cursor.toArray(cb);
});

Хотя я не уверен, что этот метод именно то, что вы ищете.

Изменить

Если вам не нужен весь массив документов, но вы хотите обрабатывать каждый из них независимо, может быть лучше использовать each вместо toArray, например

var fetchCursor = Meteor.wrapAsync(function fetchCursor (cursor, cb) {
  cursor.each(function (err, doc) {
    if (err) return cb(err);
    if (!doc) return cb(null, { done: true }); // no more documents
    // do something with the document ...
  });
});
person Tomasz Lenarcik    schedule 20.07.2016
comment
Не будет ли это перегружено памятью? Как мне сделать cursor.forEach с этим? - person Cees Timmerman; 20.07.2016
comment
myData.forEach() работает, так как содержит только небольшие словари. - person Cees Timmerman; 20.07.2016
comment
Или нет: FATAL ERROR: Evacuation Allocation failed - process out of memory @ AppData\Local\.meteor\packages\meteor-tool\1.1.10\mt-os.windows.x86_32\tools\utils\fiber-helpers.js:168. Однако до тех пор нет тайм-аута. - person Cees Timmerman; 20.07.2016
comment
Вместо toArray можно использовать each. - person Tomasz Lenarcik; 20.07.2016
comment
@CeesTimmerman Я добавил пример с each, как вы предложили. - person Tomasz Lenarcik; 20.07.2016