akka 使用tell构建Rest API

xn1cxnb4  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(150)

我正在尝试使用akka和akka-http创建REST API的好方法。根据文档,请求/回复不是参与者之间通信的最佳解决方案。因此,我的问题是如何使用tell实现类似于此片段的功能?

for {
    randomNumber <- (actor1 ? GetRandomNumber).mapTo[Int]
    randomString <- (actor2 ? GetRandomString).mapTo[String]
  } yield s"Random String: $randomString, Random Number: $randomNumber"
qhhrdooz

qhhrdooz1#

您可以封装从其他参与者收集响应的状态,并在完全提供该状态时对其进行处理。
若要用代码对此进行解释,请考虑以下示例

case class State(string: Option[String], int: Option[Int])

class CombiningActor(stringActor: ActorRef, intActor: ActorRef)
    extends Actor {

  override def receive: Receive = { case _ =>
    stringActor ! "Get Random String"
    intActor ! "Get Random Int"
    context.become(onMessage(State(string = None, int = None)))
  }

  private def onMessage(state: State): Receive = {
    case msg: String =>
      val newState = state.copy(string = Option(msg))
      whenSateFullyProvided(newState)
      context.become(onMessage(newState))
    case msg: Int =>
      val newState = state.copy(int = Option(msg))
      whenSateFullyProvided(newState)
      context.become(onMessage(newState))
  }

  private def whenSateFullyProvided(state: State): Unit = {
    if (state.string.nonEmpty && state.int.nonEmpty) {
      // Process the state here
    }
  }
}

状态累积是在context.become的帮助下发生的,context.become
将使用者的行为更改为新的“Receive”(PartialFunction[Any,Unit])处理程序。替换行为堆栈顶部的当前行为。
请注意,如果您的参与者要同时处理其他消息,则行为开关的处理会更加复杂。
如果不想使用context.becomeprivate var state: State作为变量字段也可以使用CombiningActor来达到同样的效果。
最后要注意的是,请不要在无类型的参与者中使用原语类型。如果两个不同的参与者发送相同的原语类型,代码很难理解,而且可能会出现问题。

相关问题