使用Rest API的Akka Actor热插拔

法尼

调用rest api后,我想将actor的路由切换到其他路由。请参见下面的代码。

几个问题:

  1. 代码可以正常编译,但是当启动应用程序并进行http调用时,我的配置注册超时时间为1秒,已停止,消息停止并且我没有收到服务器的任何响应。
  2. 我希望能够通过api将路由切换到另一组路由。

制成

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

}
dk14

runRoute是一个部分应用的函数,因此您不能只是编写runRoute(routeName)调用该函数,它只会返回另一个函数(处理路由),而无需调用它。您应该显式传递请求对象:

def receive = {
      case Swap =>
           become {
             case Swap => unbecome()
             case x    => val f = runRoute(otherRoutes); f(x)
           }
      case x => val f = runRoute(myRoute); f(x)
  } 

runRoute(route)返回处理“已连接”消息的函数。因此,这就是为什么您收到“注册超时”错误的原因-您不会从receive方法返回此函数。当您编写def receive = runRoute(route)此函数时,它将用作处理程序,一切都很好。但是,当您编写def receive = {case _ => runRoute(route)}任何内容时都不会发生-receive函数不执行任何操作,因为by返回的函数runRoute(route)无处可去。

参见https://github.com/spray/spray/blob/master/spray-routing/src/main/scala/spray/routing/HttpService.scala

另外,由于您已经具有MyServiceActor作为自类型,因此您也可以直接从路线呼叫“变得/变得不受欢迎”。当您使用单独的Swap消息时,actor可能会在收到成功的“交换”响应后稍稍更改其角色(角色更改将异步发生)

case object Swap
class MyServiceActor extends Actor with MyService with akka.actor.ActorLogging {

  implicit def actorRefFactory = context
  import context._

  def swapped = {
      case x => val f = runRoute(otherRoutes); f(x)
  }

  def receive = {
      case x => val f = runRoute(myRoute); f(x)
  } 
}


trait MyService extends HttpService { this: MyServiceActor =>

  implicit val timeout: Timeout = Timeout(15.seconds)

  implicit val system = context.system

  val myRoute = {
    pathSingleSlash {
      get {
            complete("MyRoute")
      }
    } ~ path("swap") {
        get {
            become(swapped)
            complete("Swapped")
        }
    }
  }

  val otherRoutes = { 
   pathSingleSlash {
     get {
      complete("OtherRoutes")
     }
   } ~ path("swap") {
     get{
        unbecome()
        complete("Reverted")
     }
   }
  }
}

更新:您的路径匹配器也不正确。使用:

 pathSingleSlash {
   ...
 } ~ path("swap") {
     ...
 }

或者

 path("swap") {
     ...
 } ~ path("") { //matches everything else
     ...
 } 

更新2:

确保您的演员在您的Main中注册为单身人士:

import akka.io.IO
import spray.can.Http

implicit val system = ActorSystem()

val myListener: ActorRef = Props[MyServiceActor]

IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)

http://spray.io/documentation/1.1-SNAPSHOT/spray-can/http-server/#http-server

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章