使用 tell 构建 Rest API
Build Rest API using tell
我正在尝试找出使用 akka 和 akka-http 创建 REST API 的好方法。根据文档,request/reply 不是参与者间通信的最佳解决方案。所以我的问题是如何使用 tell 实现类似于此代码段的内容?
for {
randomNumber <- (actor1 ? GetRandomNumber).mapTo[Int]
randomString <- (actor2 ? GetRandomString).mapTo[String]
} yield s"Random String: $randomString, Random Number: $randomNumber"
您可以封装一个状态来收集其他参与者的响应,并在完全提供时对其进行处理。
要在代码中解释这一点,请考虑以下示例
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
的帮助下发生的,
Changes the Actor's behavior to become the new 'Receive'
(PartialFunction[Any, Unit]) handler. Replaces the current behavior on
the top of the behavior stack.
请注意,如果您的 actor 应同时处理其他消息,则行为切换的处理会更加复杂。
如果您不想使用 context.become
,private var state: State
作为 CombiningActor
的变量字段也可以用来获得相同的结果。
最后一点,请不要对未类型化 actor 中的消息使用原始类型。很难理解代码,如果两个不同的参与者发送相同的原始类型可能会出现问题。
我正在尝试找出使用 akka 和 akka-http 创建 REST API 的好方法。根据文档,request/reply 不是参与者间通信的最佳解决方案。所以我的问题是如何使用 tell 实现类似于此代码段的内容?
for {
randomNumber <- (actor1 ? GetRandomNumber).mapTo[Int]
randomString <- (actor2 ? GetRandomString).mapTo[String]
} yield s"Random String: $randomString, Random Number: $randomNumber"
您可以封装一个状态来收集其他参与者的响应,并在完全提供时对其进行处理。
要在代码中解释这一点,请考虑以下示例
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
的帮助下发生的,
Changes the Actor's behavior to become the new 'Receive' (PartialFunction[Any, Unit]) handler. Replaces the current behavior on the top of the behavior stack.
请注意,如果您的 actor 应同时处理其他消息,则行为切换的处理会更加复杂。
如果您不想使用 context.become
,private var state: State
作为 CombiningActor
的变量字段也可以用来获得相同的结果。
最后一点,请不要对未类型化 actor 中的消息使用原始类型。很难理解代码,如果两个不同的参与者发送相同的原始类型可能会出现问题。