我想知道以下代码是否会关闭map函数中'ask'回调'中的id值。
val id = if (model.id.isEmpty) UUID.randomUUID().toString else model.id
val result = couchbaseActor ? SetDoc(s"user:$id", model.toJson.compactPrint)
result map {
case true => sender ! Right(Success(id))
case false => sender ! Left(makeFailureFromErrorEnum(ErrorCode.DbSaveFailed, List("User", "Error occurred while saving to Couchbase")))
}
谢谢,Aaron
最终解决方案:
消息处理程序:
case SaveUserReq(model) => saveDocument[User](sender, "User", model.id, model)
定义:
def saveDocument[T:JsonWriter](requester: ActorRef, prefix: String, id: String, model: T): Unit = {
couchbaseActor ? SetDoc(s"${prefix.toLowerCase}:$id", model.toJson.compactPrint) map {
case true => requester ! Right(Success(id))
case false => requester ! Left(makeFailureFromErrorEnum(ErrorCode.DbSaveFailed, List(prefix, errorCouchbaseSaveFailed)))
}
}
感谢所有协助的人。
答案 0 :(得分:3)
sender / getSender()会消失,为什么?
“当使用将来的回调时,你需要小心避免关闭包含actor的引用,即不要在回调中调用方法或访问封闭actor上的可变状态。这打破了actor封装并可能引入同步错误和竞争条件,因为回调将同时安排到封闭的actor。不幸的是,还没有办法在编译时检测这些非法访问。
在Actors和JMM的文档中阅读更多相关信息“
答案 1 :(得分:2)
嗯,我认为id
按原样使用。这是一个常数,不是吗?
Victor Klang提供错误来源:访问sender
actor的this
方法。您的代码实际上看起来像
val id = if (model.id.isEmpty) UUID.randomUUID().toString else model.id
val result = couchbaseActor ? SetDoc(s"user:$id", model.toJson.compactPrint)
result map {
case true => this.sender.tell(Right(Success(id)), self)
case false => this.sender.tell(Left(makeFailureFromErrorEnum(ErrorCode.DbSaveFailed, List("User", "Error occurred while saving to Couchbase"))), self)
}
似乎关闭this
。
可能通过以下方式重写代码:
val id = if (model.id.isEmpty) UUID.randomUUID().toString else model.id
val theSender = sender
val result = couchbaseActor ? SetDoc(s"user:$id", model.toJson.compactPrint)
result map {
case true => theSender ! Right(Success(id))
case false => theSender ! Left(makeFailureFromErrorEnum(ErrorCode.DbSaveFailed, List("User", "Error occurred while saving to Couchbase")))
}
可以提供帮助。
答案 2 :(得分:1)
是的,应该
根据闭包的定义