master.tell не могу получить или рассчитать - PullRequest
0 голосов
/ 07 июля 2019

Я пытаюсь создать актера для вычисления Пи Грегори-Лейбница с помощью 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);
        }
    }
}

Любая помощь?

...