2017-11-05 4 views
0

Ich habe eine routes-Klasse (Absender), einen Akteur und eine Hilfsklasse. Von der Route-Klasse sende ich eine Anfrage an den Schauspieler und bekomme eine Future-Antwort. Jetzt möchte ich die zukünftige Antwort an den Helfer weitergeben und ihn dort lösen.[Scala, Akka]: Future onComplete wird nicht außerhalb des Absenders ausgeführt

TestRoute.scala:

val response: Future[Any] = (actor ? request) (timeout) 
handler(response)(executionContext) 

TestHelper.scala:

def handler(futureResponse: Future[Any])(implicit ec: ExecutionContext): StandardRoute = { 
    onComplete(futureResponse) { 
    case Success(s) => complete(s) 
    case Failure(f) => reject 
    } 
} 

Das Problem ist, dass während onComplete Werke aus TestRoute.scala, es funktioniert nicht, wenn zu TestHelper.scala bewegt. Irgendwelche Ideen, was das Problem sein könnte?

EDIT: Mit „es nicht‚funktioniert, dann meine ich, dass die gesamte onComplete Funktion wird übersprungen und nicht ausgeführt - keine Fehler, nur über überspringt

+0

Was genau meinen Sie mit „es funktioniert nicht“? – Pedro

+0

Ihre Frage braucht mehr Kontext. Nach dem, was ich sagen kann, sollte Ihre Handler-Funktion entweder eine neue Future [StandardRoute] oder eine Einheit zurückgeben, wenn sie eine Nebenwirkung hat. – zlace

+0

Der Code sieht für mich ungefähr OK aus, wie trainierst du es, wenn du sagst, dass es "nur übersprungen" wird? Haben Sie versucht, print/log-Anweisungen hinzuzufügen, um sicherzustellen, dass keiner der Fälle ausgewertet wird? –

Antwort

0

Es gibt nur wenige. ‚Merkwürdigkeiten‘ mit Ihrem Code dass kann das Problem erklären.

1.Ich bin überrascht, dass der Code selbst gegeben kompiliert, dass futureResponse vom Typ Future[Any]. You should use mapTo die Any auf einen bekannten Typ zu konvertieren T. die Art und Weise Sie den Code jetzt aufgebaut haben impliziert dass es einen Marshaller für Any gibt, der m ay verfügbar sein in TestRoute aber nicht in TestHelper.

2. Die Tatsache, dass response ein val ist und kein def bedeutet, dass die Actor wird nur einmal abgefragt werden, statt einmal pro Anfrage. Ich glaube, Sie wollen so etwas wie:

type Output = ??? 

val response:() => Future[Output] = 
() => (actor ? request) (timeout) andThen (_.mapTo[Output]) 

, die die Unterschrift des Handlers ändern würde:

def handler(futureResponse:() => Future[Output])(implicit ec: ExecutionContext): StandardRoute = 
    onComplete(futureResponse()) { 
    case Success(s) => complete(s) 
    case Failure(f) => reject 
    } 
Verwandte Themen