Я пытаюсь создать актера для вычисления Пи Грегори-Лейбница с помощью akka, но не могу получить доступ к getSelf при вызове master.tell, и я не уверен, что делаю неправильно.Из master.tell не могу получить getSelf или Calculate, и я не совсем уверен, правильно ли я делаю.В любом случае, я мог бы также провести рефакторинг этого модуля Akka?Код здесь: https://github.com/Knox316/Akka/tree/master/src/main/java/com/actors/leibniz Действительно отчаянно пытается решить эту проблему.
Слушатель
package com.actors.leibniz;
import akka.actor.UntypedAbstractActor;
import akka.actor.UntypedActor;
import static com.actors.montecarlo.Main.DARTS_PER_ACTOR;
public class Listener extends UntypedAbstractActor {
public void onReceive(Object message) {
if (message instanceof Pi.PiApproximation) {
Pi.PiApproximation approximation = (Pi.PiApproximation) message;
System.out.println(String.format("\n\tPi approximation: \t\t%s\n\tCalculation time: \t%s",
approximation.getPi(), approximation.getDuration(), getSelf()));
getSender().tell(approximation.getPi(), getSelf());
getContext().system().terminate();
} else {
unhandled(message);
}
}
}
Master
package com.actors.leibniz;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedAbstractActor;
import akka.actor.UntypedActor;
import akka.routing.ActorRefRoutee;
import akka.routing.RoundRobinPool;
import javafx.util.Duration;
import java.util.concurrent.TimeUnit;
public class Master extends UntypedAbstractActor {
public final int nrOfMessages;
public final int nrOfElements;
public double pi = 0;
public int nrOfResults;
public final long start = System.currentTimeMillis();
public final ActorRef listener;
public final ActorRef workerRouter;
public Master(final int nrOfWorkers, int nrOfMessages, int nrOfElements, ActorRef listener) {
this.nrOfMessages = nrOfMessages;
this.nrOfElements = nrOfElements;
this.listener = listener;
/*workerRouter = this.getContext().actorOf(Props.create(Worker.class).withRouter(new RoundRobinRouter(nrOfWorkers)),
"workerRouter");*/
workerRouter = this.getContext().actorOf(new RoundRobinPool(nrOfWorkers).props(Props.create(Worker.class)), "workerRouter");
}
public void onReceive(Object message) {
if (message instanceof Pi.Calculate) {
for (int start = 0; start < nrOfMessages; start++) {
workerRouter.tell(new Pi.Work(start, nrOfElements), getSelf());
}
} else if (message instanceof Pi.Result) {
Pi.Result result = (Pi.Result) message;
pi += result.getValue();
nrOfResults += 1;
if (nrOfResults == nrOfMessages) {
// Send the result to the listener
long duration = ((System.currentTimeMillis() - start)/1_000_000_000);
listener.tell(new Pi.PiApproximation(pi, duration), getSelf());
// Stops this actor and all its supervised children
getContext().stop(getSelf());
}
} else {
unhandled(message);
}
}
}
Pi
package com.actors.leibniz;
import akka.actor.*;
import java.time.Duration;
public class Pi {
static int messages = 10_000;
static int elements = 1_000_000;
public static void main(String[] args) {
Pi pi = new Pi();
pi.calculate(4, messages, elements);
}
// actors and messages ...
public void calculate(final int nrOfWorkers, final int nrOfMessages, final int nrOfElements) {
// Create an Akka system
ActorSystem system = ActorSystem.create("PiSystem");
// create the result listener, which will print the result and shutdown the system
//final ActorRef listener = system.actorOf(new Props(Listener.class), "listener");
ActorRef listener = system.actorOf(Props.create(Listener.class), "listener");
class getMaster {
Master m = new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
}
// create the master
ActorRef master = system.actorOf(Props.create(getMaster.class), "master");
/*ActorRef master = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedAbstractActor create() {
return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
}
}), "master");*/
// start the calculation
master.tell(0, getSelf()) ;
}
static class Calculate {
}
static class Work {
private final int start;
private final int nrOfElements;
public Work(int start, int nrOfElements) {
this.start = start;
this.nrOfElements = nrOfElements;
}
public int getStart() {
return start;
}
public int getNrOfElements() {
return nrOfElements;
}
}
static class Result {
private final double value;
public Result(double value) {
this.value = value;
}
public double getValue() {
return value;
}
}
static class PiApproximation {
private final double pi;
private final long duration;
public PiApproximation(double pi, long duration) {
this.pi = pi;
this.duration = duration;
}
public double getPi() {
return pi;
}
public long getDuration() {
return duration;
}
}
}
Рабочий
package com.actors.leibniz;
import akka.actor.UntypedActor;
public class Worker extends UntypedActor {
/*static BigDecimal ONE = new BigDecimal(1);
static BigDecimal TWO = new BigDecimal(2);
static BigDecimal FOUR = TWO.pow(2);*/
public double calculatePiFor(int start, int nrOfElements) {
double acc = 0;
for (int i = start * nrOfElements; i <= ((start + 1) * nrOfElements - 1); i++) {
acc += calculatePiFor(i);
}
return acc;
}
public static double calculatePiFor(int elem) {
return (4.0 * (1 - (elem % 2) * 2)) / (2 * elem + 1);
}
public void onReceive(Object message) {
if (message instanceof Pi.Work) {
Pi.Work work = (Pi.Work) message;
double result = calculatePiFor(work.getStart(), work.getNrOfElements());
getSender().tell(new Pi.Result(result), getSelf());
} else {
unhandled(message);
}
}
}
Любая помощь?