is from 1973 ➡ Process, Store, and Communicate • An actor should follow three axioms: ➡ Create new actors ➡ Send messages to actors ➡ Designate how to handle the next message
Akka actors give the illusion of a single threaded programming model • The programming model stays the same regardless of target environment • Akka actors are location transparent
Long) class AccountActor extends Actor with ActorLogging { var accountSum = 0L // example of state in an actor def receive = { case Deposit(sum) => accountSum += sum logStatus case Withdraw(sum) => if (sum <= accountSum) accountSum -= sum logStatus } def logStatus = log.info(s"Account sum is: $accountSum") }
ActorRef = system.actorOf(Props[AccountActor], "account1") account1 ! Deposit(100L) account1 ! Withdraw(200L) account1 ! Withdraw(99L) LOG OUTPUT WHEN RUNNING THE SYSTEM: Account sum is 100 Account sum is 100 Account sum is 1
awesome, but there are scenarios that are better handled by Streams. •Example: There is no backpressure with Akka Actors and all internal queues are unbounded by default. •Have you ever tried drinking from a fire hose?
standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols." www.reactive-streams.org
Processed element by element • Processed asynchronously: ➡ Sender and receiver are decoupled ➡ Asynchronous boundaries (threads) ➡ Network boundaries (nodes)
items • java.util.concurrent.Flow.Subscriber ➡ Receiver of messages • java.util.concurrent.Flow.Subscription ➡ Message control linking a Publisher and Subscriber • java.util.concurrent.Flow.Processor ➡ Component that acts like both Publisher and Subscriber
val materializer = ActorMaterializer() val source = Source(1 to 10000) val flow = Flow[Int].filter(_ % 2 == 0).map(_.toString()) val sink = Sink.foreach[String](n => s"Even number is: $n") val runnable = source.via(flow).to(sink) runnable.run()
we are implementing. ➡ Service B: existing service that we re-use. • Service B has a quite tough SLA to meet: ➡ Not too many simultaneous calls (max 5.) ➡ Not too many frequent calls (max 1/s.)
that annoying, and astute(!), colleague we all have… - "This sounds all good, but have you heard about Akka Streams and all it’s awesome features? You should definitely give it a try and see if it can help simplify the code base a little?" - "Okay, if you say so…"