Concurrency — на самом деле важно, заняты ли параллельные треды совместной работой.
Все знают, что разделяемое состояние — плохая идея. Альтернатива — передача immutable-сообщений для обмена данными.
Эксепшены в многопоточной программе — головная боль. Альтернатива — supervision hierarchies.
Переход от одной машины к кластеру.
Точки расширения: mailboxes, dispatchers.
Дополнительные возможности: транзакционная память.
2. Зачем
• Акторы — объекты, которые вместо того чтобы
просто хранить состояние еще и выполняют код
конкурентно.
• Разделяемое состояние — это плохо, только
иммутабельные сообщения.
• Ручная синхронизация — это утомительно
3. !
class MyActor extends Actor {!
val log = Logging(context.system, this)!
def receive = {!
case "test" => log.info("received test")!
case _ => sender ! “what’s this?”!
}!
}
6. Supervision hierarchies
• Акторы образуют иерархию
• Родитель следит за детьми и может либо
перезапускать их в ответ на ошибку, не делать
ничего, либо передавать управление наверх.
7. Индивидуальные ошибки
!
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")
9. Кластеризация
• Кластер — совокупность узлов, которые с
заранее известной степенью точности находятся
в соглашении относительно того, кто входит в
кластер, и кто его возглавляет.
• Amazon Dynamo
11. Dispatchers
• Дают акторам процессорное время.
• Например, можно балансировать нагрузку между
акторами.
• Изолировать пулы потоков, потребляемые
группами акторов (Bulkheading).
12. STM
• Атомарные обновления внутреннего состояния.
Например, для случаев, когда вы не хотите
рестартовать актор целиком.
• Выглядит как блок atomic {…}, внутри которого
присваивания внутри особого вида контейнеров
(агентов) атомарны.
13. Agents
def 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!
}!
}!
}