Upon calling a rest api, I would want to switch the actor's routing to another routes. Please see the below code.
Couple of questions:
- The code compiles fine but when the app is started and a http call is made, I get Configured registration timeout of 1 second expired, stopping message and i dont get any response from server.
- I want to be able to switch routing to another set of routes through api.
made
package com.example
import akka.actor.Actor
import akka.io.IO
import spray.httpx.RequestBuilding._
import spray.http.MediaTypes._
import spray.routing.{RoutingSettings, RejectionHandler, ExceptionHandler, HttpService}
import spray.util.LoggingContext
import scala.concurrent.Future
import spray.can.Http
import spray.http._
import akka.util.Timeout
import HttpMethods._
import akka.pattern.ask
import akka.event.Logging
import scala.concurrent.duration._
case object Swap
class MyServiceActor extends Actor with MyService with akka.actor.ActorLogging {
implicit def actorRefFactory = context
import context._
def receive = {
case Swap =>
become {
case Swap => unbecome()
case _ => runRoute(otherRoutes)
}
case _ => runRoute(myRoute)
}
}
trait MyService extends HttpService { this: MyServiceActor =>
implicit val timeout: Timeout = Timeout(15.seconds)
implicit val system = context.system
val myRoute =
{
path("") {
get {
complete("MyRoute")
}
} ~ path("swap") {
get{
self ! Swap
complete("Swapped")
}
}
}
val otherRoutes =path("") {
get {
complete("OtherRoutes")
}
} ~ path("swap") {
get{
self ! Swap
complete("Reverted")
}
}
}
runRoute is a partially applied function, so you can't just write
runRoute(routeName)
to call it - it will just return another function (which handles routes) but without calling it; you should pass the request object explicitly:runRoute(route)
returns function which handle "Connected" message. So that's why you're getting "registration timeout" error - you don't return this function from receive method. When you writedef receive = runRoute(route)
this function is used as handler and everything is fine. But when you writedef receive = {case _ => runRoute(route)}
nothing happens -receive
function do nothing because function returned byrunRoute(route)
goes nowhere.See, https://github.com/spray/spray/blob/master/spray-routing/src/main/scala/spray/routing/HttpService.scala
And also you can call become/unbecome right from your route because you already have MyServiceActor as self-type. When you use separate
Swap
message - actor may change its role a little bit after you receive successful "Swapped" response (role changing will occur asynchronously)Updated: your path matchers are also incorrect. Use:
or
Updated2:
Make sure that your actor registered as singleton in your Main:
http://spray.io/documentation/1.1-SNAPSHOT/spray-can/http-server/#http-server