1

Here is my simple routing application:

object Main extends App with SimpleRoutingApp {

    implicit val system = ActorSystem("my-system")

    startServer(interface = "0.0.0.0", port = System.getenv("PORT").toInt) {

        import format.UsageJsonFormat._
        import spray.httpx.SprayJsonSupport._

        path("") {
            get {
                complete("OK")
            }
        } ~
            path("meter" / JavaUUID) {
                meterUUID => pathEnd {
                    post {
                        entity(as[Usage]) {
                            usage =>
                                // execute some logic asynchronously
                                // do not wait for the result
                                complete("OK")
                        }
                    }
                }
            }
    }
}

What I want to achieve is to execute some logic asynchronously in my path directive, do not wait for the result and return immediately HTTP 200 OK.

I am quite new to Scala and spray and wondering if there is any spray way to solve this specific problem. Otherwise I would go into direction of creating Actor for every request and letting it to do the job. Please advice.

mkorszun
  • 4,461
  • 6
  • 28
  • 43
  • It sounds like you want to send a message to an actor or spin off a future and not wait for it to complete. – Gangstead Feb 10 '15 at 21:10
  • You could embed your logic in a `Future` if it's not too complicated or the actor is too verbose/overkill for the job. – ale64bit Feb 10 '15 at 21:54
  • There is no spray-specific way to do this - spray is a HTTP library, not a kitchen sink framework. Use any of the methods you'd usually use - `Future`s or `Actor`s or task queues are perfectly good approaches. – lmm Feb 10 '15 at 22:19

1 Answers1

3

There's no special way of handling this in spray: simply fire your async action (a method returning a Future, a message sent to an actor, whatever) and call complete right after.

def doStuffAsync = Future {
   // literally anything
}

path("meter" / JavaUUID) { meterUUID =>
  pathEnd {
    post {
      entity(as[Usage]) { usage =>
        doStuffAsync()
        complete("OK")
      }
    }
  }
}

Conversely, if you need to wait for an async action to complete before sending the response, you can use spray-specific directives for working with Futures or Actors.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235