Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Сообщение — любой неизменяемый объект реализующий интерфейс Serializable.Неверно. В общем случае, сообщение — это любой объект. Обычно по-хорошему, он должен быть эффективно неизменяемым (immutable), но тут без принуждения. Serializable же требуется, если вы хотите использовать remoting, но вам лень делать нормальную сериализацию и вы хотите ограничиться дефолтной java-вской встроенной.
ActorRef — ссылка на конкретный, гарантированно существующий актор, аналог StrongReference. Отправляя по ней сообщение существуют гарантии, что оно дойдёт, или же будет брошен exception.Неверно. Актор уже вполне может быть остановлен и уничтожен, а ActorRef у вас останется на руках. Соответственно никаких гарантий, что актор получит данное сообщение. PS: Привет DeadLetters.
Сразу в глаза бросаются некоторая расточительность — мы создаем акторы для одной операции и потом их уничтожаем.С точки зрения общей концепции Акки — во многих ситуациях это вполне себе нормально.
Теперь займёмся кодом ядра, оно выполняет две функции — распределяет работу и объединяет результаты.На практике лучше так не делать. Лучше по-возможности разделять задачи акторов. Пока вы одновременно обрабатываете ровно один запрос на поиск простых чисел, то и так сойдет. Но вы ведь не для этого решили использоваться Akka, верно? Поэтому «агрегатор результатов» лучше создавать новый под каждый запрос на поиск простого числа.
Роутер — специализированный объект, передающий входящие сообщения акторам, используя определённую стратегию их выбора. Бывает двух типов — пул и группа.«пул и группа» — это вы про разные способы инициализации роутеров?
Очевидно, что происходит при попытке актора вызвать блокирующую операцию — поток блокируется, и остальные акторы начинают обрабатываться куда медленнее. А если количество заблокированных акторов становится = количеству потоков то система замирает. Даже из такой неловкой ситуации есть выход — Future.Эм. Furure на самом деле немного о другом. Более того, ваш пример их использования совершенно не помогает для решения проблемы блокировки потоков. Если вы делаете блокирующую операцию внутри Future, то вы по-прежнему блокируете под это поток из общего пула потоков (ну или из того, который вы указали). Документация Akka описывает совсем другой рецепт решения: деление всех акторов на две группы (можно больше). Группа с «правильными» акторами, которые никогда не блокируют. В идеале — совсем без какой-либо синхронизации в каком-либо виде. И группа с «меделенными» акторами, которая может блокировать, но имеет свой отдельный выделенный и явно ограниченный пул потоков. Чаще всего — много пулов. Например пул акторов, которые работают с синхронной БД; пул для работы с сетью и т.д.
Сообщение — любой неизменяемый объект реализующий интерфейс Serializable.
Неверно. В общем случае, сообщение — это любой объект. Обычно по-хорошему, он должен быть эффективно неизменяемым (immutable), но тут без принуждения. Serializable же требуется, если вы хотите использовать remoting, но вам лень делать нормальную сериализацию и вы хотите ограничиться дефолтной java-вской встроенной.
ActorRef — ссылка на конкретный, гарантированно существующий актор, аналог StrongReference. Отправляя по ней сообщение существуют гарантии, что оно дойдёт, или же будет брошен exception.
Неверно. Актор уже вполне может быть остановлен и уничтожен, а ActorRef у вас останется на руках. Соответственно никаких гарантий, что актор получит данное сообщение. PS: Привет DeadLetters.
Теперь займёмся кодом ядра, оно выполняет две функции — распределяет работу и объединяет результаты.
На практике лучше так не делать. Лучше по-возможности разделять задачи акторов. Пока вы одновременно обрабатываете ровно один запрос на поиск простых чисел, то и так сойдет. Но вы ведь не для этого решили использоваться Akka, верно? Поэтому «агрегатор результатов» лучше создавать новый под каждый запрос на поиск простого числа.
Очевидно, что происходит при попытке актора вызвать блокирующую операцию — поток блокируется, и остальные акторы начинают обрабатываться куда медленнее. А если количество заблокированных акторов становится = количеству потоков то система замирает. Даже из такой неловкой ситуации есть выход — Future.
Эм. Furure на самом деле немного о другом. Более того, ваш пример их использования совершенно не помогает для решения проблемы блокировки потоков. Если вы делаете блокирующую операцию внутри Future, то вы по-прежнему блокируете под это поток из общего пула потоков (ну или из того, который вы указали). Документация Akka описывает совсем другой рецепт решения: деление всех акторов на две группы (можно больше). Группа с «правильными» акторами, которые никогда не блокируют. В идеале — совсем без какой-либо синхронизации в каком-либо виде. И группа с «меделенными» акторами, которая может блокировать, но имеет свой отдельный выделенный и явно ограниченный пул потоков. Чаще всего — много пулов. Например пул акторов, которые работают с синхронной БД; пул для работы с сетью и т.д.
Концепция акки строго запрещает изменяемые сообщения, только immutable. Просто нет средств языка гарантировать эту неизменяемость, посему введено соглашение.В идеальном случае — да, хорошо бы, чтобы все сообщения были Immutable. Но в реальной жизни у этого есть своя цена. На самом деле реальное условие таково: объект, передаваемый в качестве сообщения должен быть «корректно виден» (т.е. соблюдается явный happens before для всех изменений) вне зависимости от того, в каком из потоков к нему идут оращения, так как каждое сообщение может обрабатываться каждым актором в произвольном потоке из пула. Но объестение, что такое «корректно виден» и в каких случаях это условие выполняется, а в каких нет — довольно обширная и сложная тема. Поэтому авторы документации к Акке пишут, что нужен Immutable объект. Это просто и понятно. Но более жестко, чем на самом деле требуется.
К примеру, если идёт обработка отдельных пакетов (игровая логика, HTTP) — создание актора для каждого уже расточительно, и умение находить эту грань очень важно.По поводу «создание актора для каждого уже расточительно». Если вы про создание актора под отдельный http-запрос или каждую команду с клиента, то мой ответ: нет, не расточительно. Аргументы:
Да, как вы верно указали — Future блокируется на потоке из пула, который мы указали. Именно для этого создаётся отдельный пул с множеством процессов, а Future — это инкапсулирует до уровня логики акки. В разделе о контексте выполнения я об этом говорил.Я о том, что вы говорите про проблему блокировки и предлагаете её решать с помощью Futures. Но сами Futures совершенно не помогают в проблеме блокировки потоков. Если же вы предлагаете использовать Futures только для того, чтобы выполнять их в другом контексте выполнения, то:
Реактивные акторы на java