0

I have a routes class (sender), an actor and a helper class. From the routes class, I send a request to the actor and get a Future response. Now, I want to pass the future response to the helper and resolve it there.

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
   }
}

The problem is that while onComplete works from within TestRoute.scala, it does not work when moved to TestHelper.scala. Any ideas what the problem might be?

EDIT: By "it does not work', I mean that the entire onComplete function is skipped over and not executed at all - no errors, just skips over.

  • What exactly do you mean by "it does not work"? – Pedro Nov 05 '17 at 11:49
  • Your question needs more context. From what I can tell, your handler function should either return a new Future[StandardRoute] or Unit if it's side-effecting. – zlace Nov 05 '17 at 13:03
  • The code looks roughly OK to me, how are you exercising it when you say it is "just skipped over"? Have you tried adding print/log statements to make sure neither case is evaluated? – Arnout Engelen Nov 06 '17 at 16:30

1 Answers1

0

There are few "oddities" with your code that may explain the issue.

1.I am surprised that your code even compiles given that futureResponse is of type Future[Any]. You should use mapTo to convert the Any to a known type T. The way you have the code constructed now implies that there is a Marshaller for Any which may be available in TestRoute but not in TestHelper.

2.The fact that response is a val and not a def means that the Actor will only be queried once, instead of once per request. I think you want something like:

type Output = ???

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

Which would change the signature of handler:

def handler(futureResponse: () => Future[Output])(implicit ec: ExecutionContext): StandardRoute = 
  onComplete(futureResponse()) {
    case Success(s) => complete(s)
    case Failure(f) => reject
  }
Ramón J Romero y Vigil
  • 17,373
  • 7
  • 77
  • 125