[英]Akka Actor - pipeTo - Is it inadvisable to use values from the received message in the piped reply?
我正在使用pipeTo
模式在Actor中处理Future
,看来工作正常。
在下面的示例中,我在UserProxyActor
下方进行了UserProxyActor
向UserActivityActor
询问了Get(userId)
消息。
我想在响应中包括Get消息的参数,以便接收方具有处理消息所需的一切。 例如,将活动插入具有相关userId的数据库中。
map
调用中可以使用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还是将其“关闭”?
Get
应该是一成不变的,如果是userId
将可用。
这会因为问号模式会阻塞而起作用吗?
参与者收到一条Get消息,创建一个Future,然后处理另一条消息。 完全没有阻塞。 直到完成Future或发生超时,Ask's Future才完成。
有没有更好的方式做到这一点,而我还没有遇到过?
如果repository.queryHistoricalActivities(userId)
没有阻止调用,则看起来不错。
我认为您所做的没有任何问题。
我唯一要提及的是,我个人不喜欢在演员之间进行交流时使用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秒钟,否则会收到故障,它可能无限期地等待)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.