Акка: разделение изменяемого состояния - PullRequest
3 голосов
/ 05 сентября 2011

Мне нужна одна глобальная переменная (синглтон), которая будет меняться очень редко. На самом деле он изменяется только после перезапуска субъекта и повторной инициализации переменной. Поскольку я не могу сделать это с помощью singleton val в объекте-компаньоне, я должен объявить его как var (mutable).

object UserDatabase {
    var dbConnection = "" // initializing db connection
}

Многие рекомендации, которые я читаю, всегда противоречат изменяемому состоянию. Поэтому я перемещаю переменную в класс и использую передачу сообщений для получения переменной.

class UserDatabase extends Actor{
    val dbConnection = "" // initializing db connection locally
    def receive = {case GetConnection => self.reply(dbConnection)}
}

Проблема в том, что dbConnection очень часто используется многими ... многими участниками, и постоянная отправка сообщений снижает производительность (так как akka обрабатывает почтовый ящик по одному).

Я не понимаю, как я могу сделать это без ущерба для производительности. Любая идея?

Ответы [ 4 ]

3 голосов
/ 05 сентября 2011

Возможно, использовать вместо агента?http://akka.io/docs/akka/1.2-RC6/scala/agents.html

2 голосов
/ 05 сентября 2011

Прежде всего, вы измеряли / замечали снижение производительности? Поскольку обмен сообщениями облегчен, возможно, он достаточно быстр для вашего приложения.

Тогда возможное решение: если «глобальное» состояние записывается редко, но к нему обращаются очень часто, вы можете выбрать стратегию push . Каждый раз, когда он изменяется, актер UserDatabase отправляет обновленное значение заинтересованным актерам. Затем вы можете использовать подход публикации / подписки, использовать реестр акторов, использовать пул актеров и т. Д.

class UserDatabase extends Actor{
    var dbConnection = "" // initializing db connection locally
    def receive = {
      case SetConnection( newConnection ) if dbConnection != newConnection => {
        dbConnection = newConnection
        sendUpdatedConnection(); // sends the change to every relevant actor
      }
    }
}
1 голос
/ 05 сентября 2011

Если вам не нужно использовать переменную очень часто в любом случае, может быть проще и эффективнее сделать ее java.lang.concurrent.atomic.AtomicReference или обернуть каждый доступ к ней в блоке synchronized (в переменной) , Актеры не всегда делают вещи проще и безопаснее, просто обычно.

0 голосов
/ 22 января 2014
  1. Создание множества акторов в качестве маршрутов RoundRobinRouter.
  2. Заставьте каждого актера обрабатывать соединение и фактически обрабатывать логику БД.
...