Допустим, у меня простой веб-сервер, который выделяет 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 будут висеть, ожидая ответа.
Это приводит к моим вопросам:
- Правильно ли мое понимание? Это действительно то, что происходит, или 4 потока в Default-Dispatcher управляют событием-l oop, и поэтому могут фактически обрабатывать много операций ввода-вывода одновременно, выполняя все 50 запросов одновременно (при условии, что db.findUser возвращает Future или что-то в этом роде.
- Есть ли способ (с фиксированными 100 потоками для запроса-ответа и блокирующей природой этих потоков), чтобы псевдо-параллельно выполнять код в одном и том же потоке. Поскольку это связано с IO, я ищу что-то похожее на модель event-l oop, которая есть у NodeJS, за исключением работы в том же потоке. Я просто хочу одновременно выполнять вызовы из базы данных, а не последовательно.
ПРИМЕЧАНИЕ. Я не ищу другой сервер / фреймворк. Вместо этого, учитывая то, что у меня уже есть, мне интересно, могу ли я использовать сопрограммы для увеличения параллелизма. Если нет, я могу просто выполнить запросы последовательно.