Умышленная блокировка в Akka Actors

Я понимаю, что акторы Akka не должны блокироваться, чтобы реагировать на сообщения, но как мне структурировать свою службу, где я хочу отслеживать процесс, работающий в течение неопределенного периода времени?

Например, мы используем библиотеку Amazon Kinesis Connector. Вы создаете коннектор с заданной конфигурацией, которая наследуется от Runnable, а затем вызываете метод Run(). Коннектор просто работает бесконечно, извлекая данные из Kinesis и записывая их в Amazon S3. На самом деле, если runnable возвращается, то это ошибка, и его нужно перезапустить.

Подход (1) состоит в том, чтобы просто создать дочерний актор для каждого работающего Kinesis Connector, и если метод Run() возвращает значение, вы выдаете исключение, контролирующий актор замечает исключение и перезапускает дочерний актор. Один коннектор на каждого дочернего актора на поток.

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

Какой подход будет наиболее соответствовать философии Akka, или есть какой-то другой подход, который рекомендуют люди? В общем, я хочу отловить какие-либо проблемы с любым Коннектором, и перезапустить его. Всего параллельно будет работать не более полудюжины коннекторов.


person Eric Kolotyluk    schedule 28.10.2014    source источник


Ответы (2)


Я бы выбрал подход 1. Однако следует отметить, что у акторов по умолчанию нет выделенного потока, но они совместно используют пул потоков (так называемый диспетчер, см.: http://doc.akka.io/docs/akka/2.3.6/scala/dispatchers.html). Это означает, что блокировка по своей сути опасна, потому что она истощает потоки пула, не позволяя запускаться другим незаблокированным субъектам (поскольку заблокированные акторы не помещают поток обратно в пул). Поэтому вы должны разделить блокирующие вызовы на пул выделенных участников фиксированного размера и назначить этим участникам PinnedDispatcher. Этот последний шаг гарантирует, что эти акторы не будут мешать друг другу (каждый из них имеет выделенный поток) и гарантирует, что эти акторы не будут мешать остальной части системы (все остальные акторы будут работать на других диспетчерах, обычно по умолчанию). - диспетчер). Не забудьте, однако, ограничить количество действующих лиц в PinnedDispatcher, поскольку количество используемых потоков будет расти вместе с количеством действующих лиц в этом диспетчере.

person Endre Varga    schedule 28.10.2014
comment
Мы уже использовали подход 1, но я подумал, что было бы разумно еще раз проверить, есть ли лучшее решение. - person Eric Kolotyluk; 04.11.2014

Из ваших двух вариантов я бы сказал, что 1 является более подходящим. No.2 страдает тем, что для выхода из будущего мира монады нужно где-то вызвать Await, а там указать максимальную длительность, что в вашем случае не имеет смысла.

Может быть, вы могли бы рассмотреть другие варианты, прежде чем идти на это, сложно. Несколько ключевых слов, которые могут вас вдохновить, — это потоки и распределенные каналы.

person Diego Martinoia    schedule 28.10.2014
comment
Я смотрел стримы и раздаточные каналы, но ничего вдохновляющего у меня не выскочило. Вариант 1 кажется наиболее прагматичным на данный момент. - person Eric Kolotyluk; 04.11.2014