【问题标题】:How to forward a request to another actor in Spray?如何将请求转发给 Spray 中的另一个参与者?
【发布时间】:2013-12-28 10:00:02
【问题描述】:

所以在Spray中,在做了基本的例子之后,我想扩展它来做更多的事情。这是我的路线:

val API_ROUTING_TREE: Route = pathPrefix("api") {

    pathPrefix("content") {

      pathPrefix("rendered" / Segment) {

        pageName => {

          /*Matches /block/{template}/{blockName}*/
          pathPrefix("block" / Segment) {

            templateName => {

              path(Segment) {

                blockName => (get | post) {
                   ??????????WHAT DOES GO HERE???????????????
                }

              }
            }
          }
        }
      }
    } ~
      path("structured") {
        failWith(new RuntimeException("Not Implemented"))
      }
  }

当然,由于缺少部分,这不会编译。我想要的只是将请求(或者可能是用已经提取的参数封装的请求)转发给另一个演员,比如 myActor !请求...那行不通。我找不到这方面的例子,或者它们真的不适合。

【问题讨论】:

  • 这取决于其他参与者应该如何处理请求?其他演员是否也包含路线?或者它只是为这个确切的请求产生结果?
  • 应该会产生结果,但我仍然需要 Request 对象。所以可以有整个请求,或者能够发送一个包含它的类以及其他数据。
  • 只是为了表明它可以做到,看看这个家伙代码:github.com/mhamrah/spray-sample/blob/master/src/main/scala/…

标签: scala akka actor spray


【解决方案1】:

您可以参考这个精彩的示例并查看代码 - Akka and Spray 您会发现该示例显示了如何将处理从路由委托给另一个参与者。如果您遵循它,您应该能够解决您使用“?”似乎面临的编译问题。和我一样……

【讨论】:

    【解决方案2】:

    怎么样

    complete {
        actor ? request
    }
    

    【讨论】:

    • 这是异步完成请求吗
    • 由于请求对象不在范围内,所以无法编译
    【解决方案3】:

    当调用主管播放器时,例如:

     TemplateActors.templateSupervisor ! new TemplateMessage("***POST***", 1)
    

    执行如下代码(属于同一类):

     import akka.actor.{ Actor, Props, ActorLogging }
    
     /**
     * Actor TemplateSupervisor
     */
    class TemplateSupervisor extends Actor with ActorLogging {
      import scala.concurrent.duration._
      import akka.actor.SupervisorStrategy._
      import akka.actor.OneForOneStrategy
    

    创建新的 Actor

      val templateActor = context.actorOf( Props[ TemplateActor ], "TemplateActor" ))
      val templateActor2 = context.actorOf( Props[ TemplateActorJuan ], "juan_carlos_actor" )
    

    来自Actor模板Actor的查询路径

      //log.info( "path templateActor2: " + templateActor2.path )
      //log.info( "path templateActor: " + templateActor.path       
    

    我们将消息发送给 Actor:

      // sent message
      def receive = {
        // Forward message to templateActor
        case message: TemplateMessage => templateActor forward message
      }
    
      override val supervisorStrategy = OneForOneStrategy( ) {
        case exception: Exception =>
          exception.printStackTrace( )
          log.error( exception, exception.getMessage(  ) )
          Restart
      }
    }
    
    /**
     * TemplateActor
     */
    class TemplateActor extends Actor with ActorLogging {
    
      import akka.pattern._
      import scala.concurrent.{Future, ExecutionContext}
    
      implicit val _: ExecutionContext = context.dispatcher
      val actor = context.actorSelection("//ms-service-executor/user/TemplateSupervisor/juan_carlos_actor")
      def receive = {
        case message: TemplateMessage =>
          log.info("************Realizando PING from TemplateActor")
          actor ! new PING( "PING" )
        case message: PONG =>
          log.info("************PONG make in TemplateActor")
      }
    }
    
    /**
     * TemplateActorJuan
     */
    class TemplateActorJuan extends Actor with ActorLogging {
    
      import akka.pattern._
      import scala.concurrent.{Future, ExecutionContext}
      implicit val _: ExecutionContext = context.dispatcher
      val actor = context.actorSelection("//ms-service-executor/user/TemplateSupervisor/TemplateActor")
      def receive = {
        case message: PING =>
          log.info("************make PONG from TemplateActorJuan")
          actor ! new PONG( "PONG" )
      }
    }
    
    case class PING( val id: String )
    case class PONG( val id: String )
    

    模板演员类

    import akka.actor.{ Props, ActorSystem }
    import TemplateSupervisor
    
    /**
     * Method override for the unique ActorSystem instance
     */
    trait Core {
      implicit def system: ActorSystem
    }
    
    /**
     * Definition of the ActorSystem and the ExecutionContext
     */
    trait BootedCore extends Core {
      import scala.concurrent.ExecutionContext
    
      implicit lazy val system = ActorSystem( "ms-service-executor" )
      implicit lazy val ex: ExecutionContext = system.dispatcher
      sys.addShutdownHook( system.shutdown( ) )
    }
    
    /**
     * Template project actors instantiation
     */
    trait CoreActors { this: Core =>
      /*
      * Creacion del actor "TemplateSupervisor"
      * Props: configuracion del actor
      * system: unico actor existente
      */
      val templateSupervisor = system.actorOf( Props[ TemplateSupervisor ], "TemplateSupervisor" )
    }
    
    /**
     * Template actor references
     */
    object TemplateActors extends BootedCore with CoreActors
    

    【讨论】:

      【解决方案4】:

      一个最小的工作示例如下:

      首先你定义你的演员:

      class MiningActor extends Actor {
         private val timeRemaining = 10
      
         override def receive = {
            case RemainingMiningTime => sender ! timeRemaining
         }
      }
      
      object RemainingMiningTime
      

      然后,您可以将其链接到您最喜欢的喷涂路线

      lazy val miningRoute = {
      get {
        path("mining" / "remaining") {
          complete {
            (miningActor ? RemainingMiningTime).mapTo[Int]
              .map(s => s"Your amber will be mined in $s")
          }
        }
      }
      

      }

      参考:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        相关资源
        最近更新 更多