Я пытаюсь перебрать все строки («документы»?) В базе данных MongoDB с помощью Morphia. Иногда я получаю следующую трассировку стека:Morphia/MongoDB: can not getmore
com.mongodb.MongoInternalException: can't do getmore
at com.mongodb.DBApiLayer$Result._advance(DBApiLayer.java:378)
at com.mongodb.DBApiLayer$Result.hasNext(DBApiLayer.java:356)
at com.mongodb.DBCursor._hasNext(DBCursor.java:436)
at com.mongodb.DBCursor.hasNext(DBCursor.java:456)
at com.google.code.morphia.query.MorphiaIterator.hasNext(MorphiaIterator.java:40)
at
В файле журнала MongoDB я вижу следующее:
$ grep "cursorid not found" output.log
Sun Feb 6 12:14:35 [conn13] getMore: cursorid not found App 2079575931792020691
Sun Feb 6 12:44:17 [conn19] getMore: cursorid not found App 8364953818630631317
Sun Feb 6 13:08:42 [conn20] getMore: cursorid not found App 7142256996888968009
Мой код для итерации довольно проста:
for (App app : datastore.createQuery(App.class).fetch())
{
log.info("app: " + app.getId());
// do stuff with app
}
Morphia ошибка? Ошибка MongoDB? Моя ошибка?
Update:
Я также видел это в моих GlassFish журналах:
[#|2011-02-16T15:39:58.029+0000|WARNING|glassfish3.0.1|com.mongodb.TRACE|_ThreadID=28;_ThreadName=Thread-1;|The log message is null.
java.lang.NullPointerException
at com.mongodb.DBApiLayer._cleanCursors(DBApiLayer.java:113)
at com.mongodb.DBApiLayer$DBCleanerThread.run(DBApiLayer.java:494)
at java.lang.Thread.run(Thread.java:662)
Я попытался как можно больше упростить код, задавая свой вопрос, поэтому вы правы, что я оставил потенциально полезную информацию. Что происходит в «do stuff with app»: запрос веб-службы и сохранение результатов в файл на диске. Обычно это выполняется в миллисекундах, но я добавлю некоторые проверки времени на цикл и посмотрю, нет ли там какого-либо аномального поведения, вызывающего таймаут. Благодарю. –
Просто сделал несколько раундов тестирования и узнал, что тайм-аут происходит через 45 минут в процессе итерации, и это повторяемо. Обратите внимание, что каждый проход через мой цикл итерации обычно составляет <1 секунду, поэтому он, похоже, является таймаутом для общего процесса итерации, а не задержкой между каждым вызовом Iterator.next(). –
Это не совсем так просто. Курсор, итератор, извлекает данные в пакетах с сервера; каждый вызов next() может или не может (размер партии может быть 200 +), должен разговаривать с сервером. Вы пробовали вариант disableTimeout? –