2016-08-04 2 views
0

У меня есть приложение, в котором пользователи выполняют геопространственный запрос в отношении базы данных mongo. Запрос может вернуть много тысяч результатов (~ 50k). Эти результаты затем передаются клиенту через websocket. Однако пользователи могут прервать набор результатов запроса и выполнить новый запрос. Пользователи будут часто запускать, прерывать и повторно запускать запросы порядка нескольких раз в минуту. Иногда они даже отменяют/перезапускают каждые пару секунд.Отмена работающего запроса

Вопрос в том, когда пользователь прерывает запрос, как мне отменить запрос на сервере, чтобы он не продолжал связывать ресурсы, передавая тысячи ненужных результатов? В настоящее время я вызываю destroy() на курсор, но неясно, что это фактически останавливает выполнение запроса на сервере.

Какова наилучшая практика в этом случае?

ответ

0

Вы пробовали это?

  1. db.currentOp()
  2. db.killOp (IDRETURNEDHE)

Это хороший example.

0

Ответ, это зависит от многих деталей реализации.

Если ваш сервер находится в середине результатов потоковой передачи (например, все еще не отправил или поставил все в очередь), когда сервер получает какое-то другое сообщение, что предыдущие результаты должны быть отменены, тогда вы можете общаться с этим другим потоком и сказать ему прекратить отправку. Как именно вы это сделаете, это полностью зависит от вашего кода, и вам нужно будет показать нам свой код для нас.

Скорее всего, запрос db уже давно завершен, и происходит то, что сервер находится в процессе потоковой передачи результатов клиенту. Итак, если это так, то это не тот дБ, который вы ищете, это код, который передает ответ клиенту. Поскольку node.js JS является однопоточным, единственный раз, когда другой запрос будет фактически запущен на сервере, будет, когда потоковый код был в некоторой операции записи асинхронных сообщений, ожидая завершения этого. Вам, вероятно, придется установить некоторый флаг, который был однозначно связан с конкретным пользователем, а затем ваш код потока должен был бы проверить этот флаг перед отправкой каждого фрагмента данных. Если он видит флаг отмены, он может отказаться от отправки остальных результатов.

Вы можете сделать вещи более поддающимися сокращению, явно перебирая ваши результаты (скажем, 500 за раз) и проверяя флаг отмены между отправкой каждого фрагмента.

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

+0

Уже существует код, чтобы отменить отправку результатов клиенту через websocket (что-то очень похожее на то, что вы предложили). Мой вопрос действительно специфичен для отмены выполнения запроса (и последующей потоковой передачи результатов клиенту) на уровне MongoDB. – herbrandson

+0

@herbrandson - Затем покажите нам конкретный код базы данных, о котором вы говорите, и код последовательности, который управляет, когда все будет работать. Вопросы о коде должны включать соответствующий код. – jfriend00

Смежные вопросы