Akka is a library written in Scala that simplifies writing fault-tolerant, highly scalable Java and Scala Actor model applications. It has been successfully used in the telecommunications industry. The system will hardly go down (high availability 99.9999999 per year only for Ms Downtime.)
Calculate the pi with Akka and calculate the formula:
In this way, we divide this formula into a section of each successive elements, divided into a message segment.
Then a worker actor is calculated simultaneously and the result is merged. Calculate the final result and time-consuming.
One: Calculate the actor of a paragraph
We need a working actor that calculates the and of a certain paragraph and spreads out the results.
Class Worker extends Actor { //calculation starting from start, continuous elements and def calculatepifor (Start:int, elements:int): Double = { var acc = 0.0 for (i <-start until (start + elements)) ACC + = 4.0 * (1-(i% 2) * 2)/(2 * i + 1) a CC } def receive = { //sender's reference to the sender of the current message case work (start, elements) = sender! Result (calculatepifor (start, elements)) }}
II: Create the main actor
The main actor's job is to assign tasks and to collect and process the results of the worker execution and return the finished results to the listener actor
Assigning tasks We need to create a round-robin router to simplify the process of assigning tasks evenly to workers.
A router was created, workers Worker val workerrouter = context.actorof ( props[worker].withrouter ( Roundrobinrouter (workers)), name = "Workerrouter")
For the main actor, two kinds of messages are accepted, one is the calculation and the other is the processing of the results received.
Class Master (Workers:int, Messages:int, Elements:int, listener:actorref) extends Actor { var pi:double = 0.0 var finish:int = 0 val starttime:long = System.currenttimemillis () //Create a router, start the workers worker Val Workerrouter = Context.actorof ( props[worker].withrouter (Roundrobinrouter (workers)), name = "Workerrouter") def receive = { //receive the calculated request, assign the calculated task to the case Calculate = = (i <-0 until messages) Workerrouter! Work (I * elements, elements) //receive the results of the calculation, add the results of the calculation to the PI, and determine whether the assigned task has been completed //If all executed, then send a message to the listener case Result (value) = + pi + value finish + = 1 if (finish = = messages) { Listener! Piapproximation (pi, duration = (system.currenttimemillis-starttime)) context.stop (Self)}}
Three: Monitor actor
Listen to the actor is relatively simple, receive data, direct output is good
Class Listener extends Actor { def receive = {case piapproximation (pi, duration) = = println ("End of calculation, result:" + Pi + "spents:" + Duration) }}
IV: Final Result
Package Akka.study.baseimport Akka.actor._import Akka.routing.RoundRobinRouterimport Java.util.concurrent.TimeUnitimport java.lang.system._import java.time.Durationsealed Trait Pimessagecase Object Calculate extends Pimessagecase class work (Start:int, elements:int) extends Pimessagecase class Result (value:double) ex Tends Pimessagecase class piapproximation (Pi:double, Duration:long) class Worker extends Actor {//calculation starting from start, continuous elements A and Def calculatepifor (Start:int, elements:int): Double = {var acc = 0.0 for (i <-start until (start + eleme NTS)) ACC + = 4.0 * (1-(i% 2) * 2)/(2 * i + 1) ACC} def receive = {//sender's reference case to access the sender of the current message Wo RK (start, elements) = sender! Result (calculatepifor (start, elements))}}class Master (Workers:int, Messages:int, Elements:int, Listener:actorref) ex Tends Actor {var pi:double = 0.0 var finish:int = 0 val starttime:long = system.currenttimemillis ()//created a router, Kai Workers a worker Val Workerrouter.= Context.actorof (Props[worker].withrouter (Roundrobinrouter (workers)), name = "Workerrouter") def receive = {//Received Calculate the request and assign the calculated task down to case Calculate = (i <-0 until messages) Workerrouter! Work (I * elements, elements)//receive the results of the calculation, add the results of the calculation to the PI, and determine whether the assigned task has been completed//if all executed, then send a message to the Listener case Result (value) = > pi + = value finish + = 1 if (finish = = messages) {Listener! Piapproximation (pi, duration = (system.currenttimemillis-starttime)) Context.stop (self)}}}class Listener Extends Actor {def receive = {case Piapproximation (pi, duration) + println ("End of calculation, result:" + pi + "spents:" + du Ration)}}object Pi {def main (args:array[string]) {def calculate (Workers:int, Elements:int, Messages:int) { Val system = Actorsystem ("Pisystem") Val listener = System.actorof (Props[listener], name = "Listener") Val Mas ter = System.actorof (Props (New Master (workers, messages, elements, listenER)), name = "Master") Master! Calculate} Calculate (6, 10000, 10000)}
Using Akka to calculate pi under Scala