如何将请求转发给Spray中的另一个actor?

时间:2013-12-10 18:07:21

标签: scala akka actor spray

所以在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这样的actor!请求......这不起作用。我找不到这方面的例子,或者他们真的不合适。

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

怎么样

complete {
    actor ? request
}

答案 2 :(得分:0)

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

 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

创建新演员

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

来自Actor templateActor的查询路径

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

我们将消息发送给了演员:

  // 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 )

TemplateActors类

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

答案 3 :(得分:0)

最小的工作示例如下:

首先定义你的演员:

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

}

参考: