Capisco come creare un'applicazione non bloccante basata su messaggi in akka e posso facilmente prendere in giro esempi che eseguono operazioni simultanee e restituire i risultati aggregati in un messaggio. Dove ho difficoltà è capire cosa sono le mie opzioni non bloccanti quando la mia applicazione deve rispondere a una richiesta HTTP. L'obiettivo è di ricevere una richiesta e consegnarlo immediatamente a un attore locale o remoto per eseguire il lavoro, che a sua volta lo distribuirà per ottenere un risultato che potrebbe richiedere del tempo. Sfortunatamente sotto questo modello, non capisco come potrei esprimerlo con una serie di "tell" non bloccante piuttosto che bloccare "ask". Se in qualsiasi punto della catena utilizzo un tell, non ho più un futuro per utilizzato come contenuto di risposta finale (richiesto dall'interfaccia framework http che in questo caso è finagle), ma non è importante . Capisco che la richiesta è sulla sua stessa discussione, e il mio esempio è abbastanza elaborato, ma solo provare a capire le mie opzioni di progettazione.Opzioni di non blocco di Akka quando è richiesta una risposta HTTP
In sintesi, se il mio esempio forzato di seguito può essere rielaborato per bloccare meno mi piace molto capire come. Questo è il mio primo utilizzo di akka da una leggera esplorazione di un anno fa, e in ogni articolo, documento e discussione che ho visto dice di non bloccare i servizi.
Le risposte concettuali possono essere utili ma potrebbero anche essere le stesse di quelle che ho già letto. Lavorare/Modificare il mio esempio sarebbe probabilmente la chiave per la mia comprensione del problema esatto che sto tentando di risolvere. Se l'esempio corrente è in genere ciò che deve essere fatto, anche la conferma è utile, quindi non cerco la magia che non esiste.
Notare i seguenti alias:. Importazione com.twitter.util {Future => TwitterFuture, attendono => TwitterAwait}
object Server {
val system = ActorSystem("Example-System")
implicit val timeout = Timeout(1 seconds)
implicit def scalaFuture2twitterFuture[T](scFuture: Future[T]): TwitterFuture[T] = {
val promise = TwitterPromise[T]
scFuture onComplete {
case Success(result) ⇒ promise.setValue(result)
case Failure(failure) ⇒ promise.setException(failure)
}
promise
}
val service = new Service[HttpRequest, HttpResponse] {
def apply(req: HttpRequest): TwitterFuture[HttpResponse] = req.getUri match {
case "https://stackoverflow.com/a/b/c" =>
val w1 = system.actorOf(Props(new Worker1))
val r = w1 ? "take work"
val response: Future[HttpResponse] = r.mapTo[String].map { c =>
val resp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)
resp.setContent(ChannelBuffers.copiedBuffer(c, CharsetUtil.UTF_8))
resp
}
response
}
}
//val server = Http.serve(":8080", service); TwitterAwait.ready(server)
class Worker1 extends Actor with ActorLogging {
def receive = {
case "take work" =>
val w2 = context.actorOf(Props(new Worker2))
pipe (w2 ? "do work") to sender
}
}
class Worker2 extends Actor with ActorLogging {
def receive = {
case "do work" =>
//Long operation...
sender ! "The Work"
}
}
def main(args: Array[String]) {
val r = service.apply(
com.twitter.finagle.http.Request("https://stackoverflow.com/a/b/c")
)
println(TwitterAwait.result(r).getContent.toString(CharsetUtil.UTF_8)) // prints The Work
}
}
Grazie in anticipo per tutti gli orientamenti offerti!
Grazie mille per la tua risposta rapida Travis. Questo fa ripulire il futuro e aspetta un po '. Quindi credi che l'uso delle due domande sia effettivamente richiesto (Ovviamente potrei solo vederlo in quel modo - ma volevo assicurarmi)? Aggiornerò il mio codice per includere i tuoi miglioramenti e includerò le conversioni implicite da un futuro di akka a un futuro di Twitter. Non ho ancora familiarità con l'etichetta Stack Overflow, quindi sto dando un +1 per il miglioramento. Qualsiasi informazione aggiuntiva sulle domande sarebbe utile. Grazie! – Eric
È difficile dire se le richieste siano richieste senza sapere di più di cosa sono responsabili questi attori, ma la parte importante è che chiedere non richiede il blocco (c'è un po 'di contabilità in più, ma è ancora asincrono). Suggerirei anche di mantenere esplicita la conversione tra Twitter e il futuro delle librerie standard, dovendo chiamare un metodo di conversione di solito un piccolo prezzo da pagare per evitare una potenziale confusione in un caso come questo. –
Grazie mille per l'aiuto e l'intuizione su questo Travis. Questo risolve perfettamente le mie preoccupazioni. – Eric