我正在以pipeTo
模式处理Actor中的UserProxyActor
,似乎正常。
在这个示例中,我在UserActivityActor
下面模拟了Get(userId)
并发出map
消息。
我想在响应中包括Get消息的参数,以便接收方具有处理消息所需的一切。例如,将活动与相关的userId插入数据库中。
class UserActivityActor(repository: UserActivityRepository) extends Actor {
import akka.pattern.pipe
import UserActivityActor._
implicit val ec: ExecutionContext = context.dispatcher
def receive = {
case Get(userId) =>
// user's historical activities are retrieved
// via the separate repository
repository.queryHistoricalActivities(userId)
.map(a => UserActivityReceived(userId, a)) // wrap the completed future value in a message
.recover{case ex => RepoFailure(ex.getMessage)} // wrap failure in a local message type
.pipeTo(sender())
class UserProxyActor(userActivities: ActorRef) extends Actor {
import UserProxyActor._
import akka.pattern.{ ask, pipe }
implicit val ec: ExecutionContext = context.dispatcher
implicit val timeout = Timeout(5 seconds)
def receive = {
case GetUserActivities(user) =>
(userActivities ? UserActivityActor.Get(user))
.pipeTo(sender())
}
}
调用中是否提供了userId或它被“关闭”了?/etc/passwd
答案 0 :(得分:1)
如果是地图调用中是否提供了userId或它被“封闭”了?
Get
,则 userId
应该是不变的。
这是行得通的,因为询问模式将被阻止吗?
演员收到一条Get消息,创建一个Future,然后处理另一条消息。完全没有阻塞。直到完成Future或发生超时,Ask's Future才完成。
有没有更好的方法可以做到这一点?
如果repository.queryHistoricalActivities(userId)
没有阻止通话,效果很好。
答案 1 :(得分:0)
我认为您所做的没有任何问题。
我唯一要提及的是,我个人不喜欢在演员之间进行交流时使用ask
(请记住,这在很大程度上是个人喜好),所以我会做以下事情:
class UserActivityActor(repository: UserActivityRepository) extends Actor {
import akka.pattern.pipe
import UserActivityActor._
implicit val ec: ExecutionContext = context.dispatcher
def receive = {
case Get(userId) =>
// user's historical activities are retrieved
// via the separate repository
repository.queryHistoricalActivities(userId)
.map(a => UserActivityReceived(userId, a)) // wrap the completed future value in a message
.recover{case ex => RepoFailure(ex.getMessage)} // wrap failure in a local message type
.pipeTo(sender())
class UserProxyActor(userActivities: ActorRef) extends Actor {
import UserProxyActor._
def receive = {
case GetUserActivities(user, sender()) =>
userActivities.forward(UserActivityActor.Get(user))
}
}
但是,这确实消除了超时行为(在您的原始实现中,发出请求的actor在我的系统中最多等待5秒钟,否则会无限期等待)。