я им (включая того чувака который эту херню с блокировками и ожиданиями в акторах в коде у себя пишет, вместо того чтобы фьючеры композить) показывал (ссылки, цитировал, своими словами рассказывал смысл) документацию по Akka.
почему-то эффекта это не возымело. они считают что это какая-то чисто теоретическая проблема а на практике все будет нормально как попало. то есть они что вобще делают? они считают что акторы это просто классы-потоки (как сказал этот чувак - "акторы это легковесные потоки"). они берут пишут всю бизнес-логику прямо в акторах, разбивая ее по разным классам-акторам и запускают это всё просто без какого либо конфигурирования Akka (то есть в пуле потоков по умолчанию и работают все эти акторы в одном и том же пуле все сразу). бизнес-логика предполагает выполнение запросов к базе данных, причем дофига запросов. и к тому же нужно же как то там мап-редюсить типа жеж - вот они и мап-редюсят вызывая Await на Future который возвращается из ? в акторе. получается в итоге что - акторы постоянно блокируют потоки в пуле в котором исполняются. в пуле количество потоков достаточно ограниченно (поскольку он дефолтный а там по дефолту политика такая что максимальное количество потоков определяется количеством ядер процессора умножая это количество на достаточно небольшое число вроде как 3 (три)). в результате, поскольку акторов запускается дофигища, причем даже просто в фоновом режиме - постоянно работают (шедулятся) некие процессы-акторы, которые в фоновом режиме считают и кешируют некие данные из базы - потоки в пуле все фактически заблокированны. и поэтому когда например пользователь начинает логиниться то может оказаться так что ему придется долго (в тестах например 20 секунд оказывается мало и они по таймауту отваливаются) ждать пока какой нибудь актор закончит свою работу и освободит поток для актора который пользователя залогинит. короче полный бред на мой взгляд.
причем фиксится все это предельно просто - выносим все блокирующие запросы к базе в отдельный пул акторов (через актор-роутер), который будет сконфигурирован на работу в отдельном пуле потоков. причем этот отдельный пул потоков фактически всегда будет заблокирован и будет просыпаться только тогда когда ему нужно будет забрать очередной запрос из очереди - что на самом деле происходит практически мгновенно, и потом он сразу же просто ждет ответа из базы данных (блокируется) и процессор сразу переключается на потоки из другого пула, то есть этот пул который запросы выполняет он вообще процессор не использует. а все вычислительные задачи (без блокирующих вызовов) спокойно могут через fork-join работать если их тоже правильно разбить на отдельные вычислительные функции которые будут через map асинхронно вызываться (Future's вобщем имеются ввиду).
всё это было им не один раз рассказано и даже написан был код. чувак в ответ сказал что он кода этого не понимает и будет делать как умеет (то есть через жопу)
no subject
Date: 2015-04-10 08:59 am (UTC)почему-то эффекта это не возымело. они считают что это какая-то чисто теоретическая проблема а на практике все будет нормально как попало. то есть они что вобще делают? они считают что акторы это просто классы-потоки (как сказал этот чувак - "акторы это легковесные потоки"). они берут пишут всю бизнес-логику прямо в акторах, разбивая ее по разным классам-акторам и запускают это всё просто без какого либо конфигурирования Akka (то есть в пуле потоков по умолчанию и работают все эти акторы в одном и том же пуле все сразу). бизнес-логика предполагает выполнение запросов к базе данных, причем дофига запросов. и к тому же нужно же как то там мап-редюсить типа жеж - вот они и мап-редюсят вызывая Await на Future который возвращается из ? в акторе. получается в итоге что - акторы постоянно блокируют потоки в пуле в котором исполняются. в пуле количество потоков достаточно ограниченно (поскольку он дефолтный а там по дефолту политика такая что максимальное количество потоков определяется количеством ядер процессора умножая это количество на достаточно небольшое число вроде как 3 (три)). в результате, поскольку акторов запускается дофигища, причем даже просто в фоновом режиме - постоянно работают (шедулятся) некие процессы-акторы, которые в фоновом режиме считают и кешируют некие данные из базы - потоки в пуле все фактически заблокированны. и поэтому когда например пользователь начинает логиниться то может оказаться так что ему придется долго (в тестах например 20 секунд оказывается мало и они по таймауту отваливаются) ждать пока какой нибудь актор закончит свою работу и освободит поток для актора который пользователя залогинит. короче полный бред на мой взгляд.
причем фиксится все это предельно просто - выносим все блокирующие запросы к базе в отдельный пул акторов (через актор-роутер), который будет сконфигурирован на работу в отдельном пуле потоков. причем этот отдельный пул потоков фактически всегда будет заблокирован и будет просыпаться только тогда когда ему нужно будет забрать очередной запрос из очереди - что на самом деле происходит практически мгновенно, и потом он сразу же просто ждет ответа из базы данных (блокируется) и процессор сразу переключается на потоки из другого пула, то есть этот пул который запросы выполняет он вообще процессор не использует. а все вычислительные задачи (без блокирующих вызовов) спокойно могут через fork-join работать если их тоже правильно разбить на отдельные вычислительные функции которые будут через map асинхронно вызываться (Future's вобщем имеются ввиду).
всё это было им не один раз рассказано и даже написан был код. чувак в ответ сказал что он кода этого не понимает и будет делать как умеет (то есть через жопу)