Je commence à utiliser Scala et le modèle AKKA, et j'ai écrit ce code, mais ça ne marche pas et je ne sais pas pourquoi ...Dans Akka, comment gérer les appels de méthode de blocage, comme lire depuis StdIn?
J'ai créé un petit projet qui lit l'utilisateur entrée de la console. lorsque cet utilisateur a écrit un mot-clé, l'acteur keyword (enfant) l'interprétera et communiquera avec l'acteur de la console (grand parent).
l'action Acteur sera utilisé pour diffuser et faire plus de choses. Quand j'entre la commande 'renommer' dans la console Acteur, j'entre dans l'action Acteur et ensuite dans le mot clé Acteur et j'entre dans la méthode Renommer, mais après rien, je ne rentre pas dans le renommer
méthode sur la console Acteur.
Pouvez-vous m'aider?
Si vous avez vu une mauvaise pratique, n'hésitez pas à me dire comment résoudre cela :).
Merci!
principal
import ConsoleActor._
import akka.actor.ActorSystem
object Main extends App {
val system = ActorSystem("My-Little-IRC")
val consoleActor = system.actorOf(ConsoleActor.props, "consoleActor")
consoleActor ! ReadConsoleInput
system.terminate()
}
consoleActor
import ActionActor.TreatInputUser
import akka.actor.{Actor, Props}
import scala.io.StdIn
object ConsoleActor {
case class ReadConsoleInput()
case class StopLoop()
case class Rename()
case class WhoIAm()
def props = Props[ConsoleActor]
}
class ConsoleActor() extends Actor {
val keyWordActor = context.actorOf(KeyWordActor.props(this.self), "keyWordActor")
val actionActor = context.actorOf(ActionActor.props(keyWordActor), "actionActor")
var currentUser: String = ""
var loop: Boolean = true;
import ConsoleActor._
def isValidString(str: String): Boolean = {
var isValid: Boolean = false
if (str != null && !str.trim().isEmpty)
isValid = true
isValid
}
def initiatePresentation() = {
println("Hi ! Who are you ?")
currentUser = StdIn.readLine()
println(s"Nice to meet you ${currentUser}, I'm your console app !")
}
def receive = {
case ReadConsoleInput => {
initiatePresentation
var value = ""
while (loop) {
println("Yes ?")
value = StdIn.readLine()
if (isValidString(value)) {
actionActor ! TreatInputUser(value)
}
}
}
case StopLoop => {
println("stop Loooop !")
loop = false
}
case Rename => {
println(s"${currentUser} was a good name ! Which is your new name ?")
currentUser = StdIn.readLine()
println(s"Nice to meet you -again- ${currentUser}")
}
case WhoIAm =>{
println(s"I'm ${currentUser}")
}
}
}
actionActor
import ActionActor.TreatInputUser
import akka.actor.{Actor, ActorRef, Props}
import akka.util.Timeout
import scala.concurrent.duration._
import akka.pattern.ask
import scala.concurrent.Await
object ActionActor {
case class TreatInputUser(string: String)
def props(keyWordActor: ActorRef) = Props(new ActionActor(keyWordActor))
}
class ActionActor(keyWordActor: ActorRef) extends Actor {
import KeyWordActor._
def receive = {
case TreatInputUser(string) => {
implicit val timeout = Timeout(5 seconds)
var isKeyWord = keyWordActor ? IsKeyWord(string)
val isKeyWordResult = Await.result(isKeyWord, timeout.duration).asInstanceOf[ Boolean ]
println(isKeyWordResult)
if (isKeyWordResult) {
keyWordActor ! HandleKeyWord(string)
}
else {
println("bla bla bla")
}
}
}
}
acteur de mot-clé
import ConsoleActor.{Rename, StopLoop, WhoIAm}
import akka.actor.{Actor, ActorRef, Props}
object KeyWordActor {
case class IsKeyWord(key : String)
case class HandleKeyWord(key : String)
def props(consoleActor: ActorRef) = Props(new KeyWordActor(consoleActor))
}
class KeyWordActor(consoleActor: ActorRef) extends Actor {
import KeyWordActor._
val KeysWord : Map[ String,()=> Any] = Map("rename" -> renameFunction, "stop" -> stopFunction, "42" -> uselessfunction, "john doe ?" -> AmIJohnDoe)
def renameFunction() = {
println("here")
consoleActor ! Rename
}
def stopFunction() = {
consoleActor ! StopLoop
}
def uselessfunction() = {
println("useless")
}
def AmIJohnDoe() ={
consoleActor ! WhoIAm
}
def receive = {
case IsKeyWord(key) => {
sender ! KeysWord.contains(key.toLowerCase)
}
case HandleKeyWord(key) => {
if (KeysWord.contains(key.toLowerCase)) {
KeysWord(key.toLowerCase)()
}
}
}
}
Dans 'ConsoleActor', vous bloquez dans votre méthode' receive'.[Le blocage nécessite une gestion attentive] (https://doc.akka.io/docs/akka/2.5/scala/dispatchers.html#blocking-needs-careful-management). Plutôt, lisez à partir de 'StdIn' dans' Main', et envoyez un message à 'ConsoleActor' (ou quelqu'un de approprié) quand une ligne est lue. –
Hey @ LászlóvandenHoek, quand vous avez dit que je devais lire l'entrée de l'utilisateur dans le'Main ', voulez-vous dire que la boucle' While 'doit être dans le' Main '? Si oui, comment l'acteur 'keyWord' pourra-t-il arrêter la boucle? – Brice
Mon commentaire précédent est, mais maintenant que j'ai bien compris votre question, j'ai fourni une réponse. –