Hi Andrea, Thanks for your question - I'm not sure I understand your use case completely, so I can't really comment on the overall structure, but I can answer some questions.
On Fri, May 5, 2017 at 8:41 PM, Andrea Nicolini <[email protected] > wrote: > I'm trying two ways, the first is to use "stash" and "unstash" but getting > poor results, only the first actor can submit his guess, honestly I do not > even know if logically it may be the right choice > > public void onReceive(Object message) throws Throwable { > if (!gameFinished) { > if (message instanceof GuessMsg && nRequest < nPlayers) { > unstashAll(); > if (!gameFinished && ((GuessMsg) message).getTicket().getValue() == nRequest > + 1) { > ResultMsg result = getResult(((GuessMsg) message).getGuess()); > getSender().tell(result, ActorRef.noSender()); > nRequest++; > } > > } else { > nRequest++; > stash(); > } > } else { > throw new GameFinishedException(); > } > } > > Here you seem to intend to 'stash' until you find the 'next' command, then execute the command and continue. I think you're calling 'unstashAll()' too often here: you're unstashing messages whenever 'nRequest < nPlayers', but only increase nRequest when you've found the first message to process. Because 'unstashAll()' prepends the unstashed messages to the mailbox, you'll might end up stashing and unstashing the same few messages on the front of the mailbox all the time. When you move 'unstashAll()' to after handling a command this might work better. I think I like your second approach better though: In the second way I tried to make an internal list to the actor containing the mesages, when I received them all, to rearrange them, and in each message I pass the reference to the sender object (getSelf ()) but when I send the answer it seems > > do not get to the destination and then get a timeout event: > AskTimeoutException, this is the code: > > > public void onReceive(Object message) throws Throwable { > if (!gameFinished) { > if (message instanceof GuessMsg && nRequest < nPlayers) { > > orderList.put(((GuessMsg) message).getTicket().getValue(), ((GuessMsg > ) message).getGuess()); > > if (orderList.keySet().size() == nPlayers && !gameFinished) { > Object[] keys = orderList.keySet().toArray(); > Arrays.sort(keys); > Result result = getResult(orderList.get(key)); > if (result.found()) > this.gameFinished = true; > ActorRef sender = orderList.get(key).getSender(); > sender.tell(result, ActorRef.noSender()); > } > } > } > } else { > throw new GameFinishedException(); > } > } > > > This is the request I send from Player Actor: > > > if (message instanceof TryMsg) { > Future<Object> future = Patterns.ask(this.oracle, new GuessMsg(ticket, new > Guess(id, value, getSelf())), 20000); > Result result = (ResultMsg) Await.result(future, timeout.duration()); > System.out.println("[PLAYER-" + id + "] Get Result"); > checkResult(result); > } > > What do you think? Can anyone help me? > > What's going wrong here is that 'ask' does not combine well with adding 'self' to the message. There's 2 ways to resolve this: 1) avoid using 'ask' 2) use 'ask', but don't put 'self' in the message: instead remember the 'sender()' when handling the message. I also noticed you're using `Await.result` in the Player actor. This is not allowed: it will block the thread processing the `TryMsg` message, where you'd want to be asynchonous and free up this thread to process other messages. So I'd propose going for solution '1', avoiding 'ask' here: just use `tell` (fire-and-forget) to send the message to the oracle. Now when the oracle sends its response back, it will be presented to your Player actor, so you add `ResponseMsg` to the onReceive of your Player actor and call 'checkResult' from there. Does that help? Kind regards, -- Arnout Engelen *Senior Software Engineer* E: [email protected] T: https://twitter.com/raboofje -- >>>>>>>>>> Read the docs: http://akka.io/docs/ >>>>>>>>>> Check the FAQ: >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user --- You received this message because you are subscribed to the Google Groups "Akka User List" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/akka-user. For more options, visit https://groups.google.com/d/optout.
