2015-12-24 6 views
0

Я создаю актеров в java с библиотекой akka для реализации системы аккордов. Моя цель состоит в том, чтобы заставить двух актеров послать друг другу сообщения. Но когда я делаю это, я получаю следующее сообщение об ошибке:Akka Java: обнаружены мертвые буквы

[INFO] [12/24/2015 15:27:33.521] [globalSystem-akka.actor.default-dispatcher-5] [akka://globalSystem/user/ChordActor3] Message [messages.SuccessorFoundMessage] from Actor[akka://globalSystem/user/ChordActor0#1781934127] to Actor[akka://globalSystem/user/ChordActor3#-2019697728] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. 

Вот код моего главного класса:

package classes; 

import messages.JoinMessage; 
import messages.PrintFingerTableMessage; 
import akka.actor.ActorRef; 
import akka.actor.ActorSystem; 
import akka.actor.Props; 

public class Main { 

public static void main(String[] args) { 

    final ActorSystem system = ActorSystem.create("globalSystem"); 


    ChordNode cn0 = new ChordNode(0); 
    ChordNode cn3 = new ChordNode(3); 


    final ActorRef actor0 = system.actorOf(Props.create(ChordActor.class),"ChordActor0"); 
    final ActorRef actor3 = system.actorOf(Props.create(ChordActor.class),"ChordActor3"); 


    PrintFingerTableMessage printFingerTableMessage = new PrintFingerTableMessage(); 
    JoinMessage joinMessage0 = new JoinMessage(cn0); 
    JoinMessage joinMessage3 = new JoinMessage(cn3); 


    actor0.tell(joinMessage0,null); 
    actor0.tell(printFingerTableMessage,null); 

    actor3.tell(joinMessage3, actor0); 
    actor3.tell(printFingerTableMessage,null); 


    system.shutdown(); 
} 

} 

А вот мой класс ChordActor:

package classes; 

import java.util.ArrayList; 

import messages.FindSuccessorMessage; 
import messages.JoinMessage; 
import messages.PrintFingerTableMessage; 
import messages.SuccessorFoundMessage; 
import akka.actor.ActorRef; 
import akka.actor.UntypedActor; 

public class ChordActor extends UntypedActor{ 
    private ChordNode chordNode; 
    private FingerTable fingerTable; 
    private ArrayList<Key> key = new ArrayList<Key>(); 
    private ActorRef predecessor; 
    private ActorRef successor; 

@Override 
public void onReceive(Object message) throws Exception { 


    if(message instanceof JoinMessage){ 
     this.chordNode=((JoinMessage) message).getChordNode(); 

     // if sender is null : 
     if(getSender().toString().equals("Actor[akka://globalSystem/deadLetters]")){ 
      this.fingerTable= new FingerTable(this.chordNode,getSelf()); 
      this.predecessor=getSelf(); 
      this.successor=getSelf(); 
     } 


     else{ 

      this.fingerTable= new FingerTable(this.chordNode); 
      for(int i=0;i<this.fingerTable.getTable().size();i++){ 
       FindSuccessorMessage findSuccessorMessage = new FindSuccessorMessage(this.fingerTable.getTable().get(i).getLowBound(),i); 
       getSender().tell(findSuccessorMessage, getSelf()); 
      } 
     } 
    } 


    else if(message instanceof FindSuccessorMessage){ 
     ActorRef actorRef = this.fingerTable.findSuccessor(((FindSuccessorMessage) message).getId()); 
     int ligne = ((FindSuccessorMessage) message).getLigne(); 

     SuccessorFoundMessage successorFoundMessage = new SuccessorFoundMessage(actorRef,ligne); 
     getSender().tell(successorFoundMessage,getSelf()); 
    } 


    else if(message instanceof SuccessorFoundMessage){ 
     this.fingerTable.getTable().get(((SuccessorFoundMessage) message).getligne()).setSuccessor(((SuccessorFoundMessage) message).getActorRef()); 
    } 

    else if(message instanceof PrintFingerTableMessage){ 
     System.out.println(this.fingerTable);  
    } 
} 
} 

Я искал в Интернете решения, но я действительно не понимал, как решить мою проблему.

Благодарим за помощь.

Имейте славный день!

Джонатан

+0

Привет @Jonathan, в моем маленьком приложении «иногда». Я получаю то же самое в начале моего приложения. Я думаю, что это происходит из-за инициализации актера. Если я не ошибаюсь, инициализация актера происходит асинхронно. Когда вы отправляете ресивер сообщения, он еще не готов получать сообщения. Я не уверен, что буду смотреть на эту проблему завтра для своего приложения. Если я смогу найти что-то полезное, я обновлю это. – endertunc

ответ

2

Когда вы system.shutdown() системы актера это приведет к тому, что актеры будут остановлены. Поскольку вы никоим образом не дожидаетесь завершения работы ваших актеров, они могли обработать все или, возможно, не обработали ни одно из сообщений, когда ваш основной метод завершает работу системы.

Если есть сообщения во входящей папке, когда актер остановлен, они будут отправлены в deadLetters (описано в документах здесь: http://doc.akka.io/docs/akka/2.4.1/java/untyped-actors.html#Stopping_actors).

Итак, я предполагаю, что вы разместили сообщения во входящих папках ваших участников с 4-мя вызовами tell, но затем прекратите работу, и поскольку он асинхронен, он не детерминирован, если ваши актеры обработали сообщения еще или нет , А поскольку ваши актеры отключены, сообщения, оставшиеся в почтовых ящиках, будут отправляться на адрес deadLetters.

Я не уверен, есть ли окончательное состояние, когда ваши актеры «сделаны» в вашем примере кода, поэтому с учетом того, что один из способов заставить его работать, должен блокировать, например, StdIn.readLine();, а затем shutdown. , таким образом вы можете легко попробовать вещи и решить, сколько времени вы хотите запустить приложение.

Смежные вопросы