akka и реактивное программирование на jvm
DESCRIPTION
Concurrency — на самом деле важно, заняты ли параллельные треды совместной работой. Все знают, что разделяемое состояние — плохая идея. Альтернатива — передача immutable-сообщений для обмена данными. Эксепшены в многопоточной программе — головная боль. Альтернатива — supervision hierarchies. Переход от одной машины к кластеру. Точки расширения: mailboxes, dispatchers. Дополнительные возможности: транзакционная память.TRANSCRIPT
Зачем
• Акторы — объекты, которые вместо того чтобы просто хранить состояние еще и выполняют код конкурентно.
• Разделяемое состояние — это плохо, только иммутабельные сообщения.
• Ручная синхронизация — это утомительно
!
class MyActor extends Actor {!
val log = Logging(context.system, this)!
def receive = {!
case "test" => log.info("received test")!
case _ => sender ! “what’s this?”!
}!
}
Обработка ошибок
Supervision hierarchies
• Акторы образуют иерархию
• Родитель следит за детьми и может либо перезапускать их в ответ на ошибку, не делать ничего, либо передавать управление наверх.
Индивидуальные ошибки!
val breaker =
new CircuitBreaker(context.system.scheduler,
maxFailures = 5,
callTimeout = 10.seconds,
resetTimeout = 1.minute).onOpen(notifyMeOnOpen())
def notifyMeOnOpen(): Unit =
log.warning("My CircuitBreaker is now open, and will not close for one minute")
Remoting
• Минимально затрагивает код приложения.
Кластеризация
• Кластер — совокупность узлов, которые с заранее известной степенью точности находятся в соглашении относительно того, кто входит в кластер, и кто его возглавляет.
• Amazon Dynamo
Scala
Писать на джаве можно, но выглядит это грустно.
Dispatchers
• Дают акторам процессорное время.
• Например, можно балансировать нагрузку между акторами.
• Изолировать пулы потоков, потребляемые группами акторов (Bulkheading).
STM
• Атомарные обновления внутреннего состояния. Например, для случаев, когда вы не хотите рестартовать актор целиком.
• Выглядит как блок atomic {…}, внутри которого присваивания внутри особого вида контейнеров (агентов) атомарны.
Agentsdef transfer(from: Agent[Int], to: Agent[Int], amount: Int): Boolean = {!
atomic { txn =>!
if (from.get < amount) false!
else {!
from send (_ - amount)!
to send (_ + amount)!
true!
}!
}!
}