Сервер Meteor перезапускается при медленных запросах - PullRequest
1 голос
/ 01 ноября 2019

У меня есть приложение Meteor, которое выполняет некоторые звонки, которые в данный момент зависают. Я обрабатываю много элементов в цикле, который затем загружается в серверную версию Mongo. (Я думаю, что это делается асинхронно) Я понимаю, что использование циклов не очень хорошо .

Эта целая функциональность, кажется, заставляет приложение какое-то время зависать. Я даже замечаю sock.js и ошибку websocket в консоли. Я думаю, что это все из-за DDP, асинхронных обращений Mongo и медленных запросов. Вот некоторый псевдокод к тому, о чем я говорю

for (1..A Lot of records) {
    //Is this async?
    Collection.upsert(record)
}

В конце концов эта функция завершится. Тем не менее, я заметил, что Meteor «перезапускается» (я думаю, что это правда, потому что я вижу, что Accounts.onLogin снова вызывается. Это похоже на то, что клиент обновляется после того, как медленный запрос фактически завершился. Это приводит к чему-то, что кажется бесконечнымloop.

Мой вопрос заключается в том, почему приложение «перезапускается». Это связано с чем-то в фреймворке и с тем, как оно обрабатывает медленные запросы? Т.е. оно ставит в очередь все плохие запросы и затем в конечном итоге повторяет их автоматически?

1 Ответ

1 голос
/ 02 ноября 2019

Я не уверен в том, что именно здесь происходит, но похоже, что клиент не может подключиться к серверу, пока он «занят», а затем клиентское соединение через DDP истекает и заканчиваетсяобновление клиента. Серверный процесс, вероятно, не перезапускается.

Один из способов улучшить это - создать очередь в вашей базе данных. Один фрагмент кода обнаруживает, что нужно выполнить несколько операций по обновлению базы данных, поэтому он записывает информацию в таблицу, которая используется в качестве очереди.

Вы устанавливаете задание cron (используя, например, npm module node-cron), которое ищет вещи в очереди на регулярной основе - когда он находит необработанную запись, он выполняет требуемую работу upsert, а затем либообновляет значение состояния в записи очереди на «выполнено» или просто удаляет его из очереди. Вы можете решить, сколько записей обрабатывать за один раз, чтобы минимизировать прерывания.

Другой подход заключается в том, чтобы выполнить обработку в другом узле процесса на вашем сервере, в основном, как рабочий процесс. Если этот процесс занят, это не повлияет на ваш интерфейс. Та же самая техника очередей может быть использована, чтобы убедиться, что она не застрянет.

Таким образом, вы теряете немного реактивности, но, учитывая, что это какой-то массовый процесс, это не должно иметь значения.

...