Srini K
Srini K

Reputation: 3365

How to make a method synchronous in scala?

In this method I would like to see the actual response (result.toJson.toString or StatusCodes.InternalServerError.toString) returned instead of empty string. How can I do that?

def process(msgIn : WebSocketMessageIn, service : ActorRef) : String = {
  import model.Registration
  import model.RegistrationJsonProtocol._

  implicit val timeout = Timeout(10 seconds)

  msgIn.method.toUpperCase match {
    case "POST" =>
      log.debug(s"Handing POST message with body ${msgIn.body}")
      val registration = msgIn.body.convertTo[Registration]
      val future = (service ? PostRegistrationMessage(registration)).mapTo[Registration]
      var response = ""
      future onComplete {
        case Success(result) =>
          response = result.toJson.toString

        case Failure(e) =>
          log.error(s"Error: ${e.toString}")
          response = StatusCodes.InternalServerError.toString
      }
      response

    case "PUT" =>
      s"Handing PUT message ${msgIn.body}"
  }
}

Here is the code snippet that calls the method and sends the response to websocket

case Message(ws, msg, service) =>
  log.debug("url {} received msg '{}'", ws.getResourceDescriptor, msg)
  val wsMessageIn = msg.parseJson.convertTo[WebSocketMessageIn]
  val response = process(wsMessageIn, service)
  ws.send(response);

UPDATE 1: Updated to use Await.result(future, 5000 millis) instead of 'future onComplete { ... }'. Here is code snippet that changed. Works now, but just wondering how we will handle failures.

msgIn.method.toUpperCase match {
  case "POST" =>
    log.debug(s"Handing POST message with body ${msgIn.body}")
    val registration = msgIn.body.convertTo[ADSRegistration]
    val future = (service ? PostADSRegistrationMessage(registration)).mapTo[ADSRegistration]
    val response = Await.result(future, 5000 millis)
    response.toJson.toString

Upvotes: 0

Views: 3846

Answers (1)

Justin Pihony
Justin Pihony

Reputation: 67135

You can use Await.result which is blocking. Something like this:

import scala.concurrent.duration._
val result = Await.result(future, atMost = 10.second)
val response = //result processing

Just the same, you could pass the future back and perform the send in the onComplete which would be much more reactive

Upvotes: 6

Related Questions