Сопрограммы для параллелизма в запросе-ответе - PullRequest
1 голос
/ 07 марта 2020

Допустим, у меня простой веб-сервер, который выделяет 100 потоков для обработки входящих запросов. Когда приходит запрос, поток назначается и блокируется до получения ответа. Как только ответ становится доступным, ответ отсылается, и поток снова становится свободным.

Чтобы обработать запрос, мне нужно сделать 2 вызова базы данных и в основном суммировать результаты:


    suspend fun getUserData(username: String): String = {
      val firstName = async { database1.findUser(username) } // a suspended function
      val lastName = async { database2.findUser(username) } // a suspended function
      return firstName.await() + lastName.await();
    }

Допустим, у меня был метод main, который вызывает вышеуказанный метод для обслуживания запроса:


    fun main(username) {
      runBlocking {
        return userData(username)
      }
    }

Насколько я понимаю, асин c код в getUserData будет работать поверх диспетчера по умолчанию с столько ядер, сколько процессоров.

Это предполагает следующее:

  • В дополнение к 100 потокам, которые я обрабатываю, у меня также есть еще один (меньший) пул потоков ~ 4-8 потоков, которые обрабатывают вызовы базы данных.
  • Предполагается, что у меня есть 4 ЦП, и предполагается, что каждый вызов БД занимает ~ 750 мс: если я начинаю получать 50 запросов в секунду, 4 потока, обрабатывающие сопрограмму, будет заблокировано 4-мя запросами, остальные 44 будут висеть, ожидая ответа.

Это приводит к моим вопросам:

  1. Правильно ли мое понимание? Это действительно то, что происходит, или 4 потока в Default-Dispatcher управляют событием-l oop, и поэтому могут фактически обрабатывать много операций ввода-вывода одновременно, выполняя все 50 запросов одновременно (при условии, что db.findUser возвращает Future или что-то в этом роде.
  2. Есть ли способ (с фиксированными 100 потоками для запроса-ответа и блокирующей природой этих потоков), чтобы псевдо-параллельно выполнять код в одном и том же потоке. Поскольку это связано с IO, я ищу что-то похожее на модель event-l oop, которая есть у NodeJS, за исключением работы в том же потоке. Я просто хочу одновременно выполнять вызовы из базы данных, а не последовательно.

ПРИМЕЧАНИЕ. Я не ищу другой сервер / фреймворк. Вместо этого, учитывая то, что у меня уже есть, мне интересно, могу ли я использовать сопрограммы для увеличения параллелизма. Если нет, я могу просто выполнить запросы последовательно.

...