2

我想知道以下代码是否会关闭地图函数中询问“回调”中的 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")))
  }

谢谢,亚伦

最终解决方案:

消息处理程序:

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)))
  }
}

感谢所有提供帮助的人。

4

3 回答 3

3

当我在我的 Actor 中使用 Future 时,sender/getSender() 消失了,为什么?

“在使用未来回调时,在 Actor 内部,您需要小心避免关闭包含 Actor 的引用,即不要从回调内部调用方法或访问封闭 Actor 上的可变状态。这会破坏 Actor 封装并可能引入同步错误和竞争条件,因为回调将同时调度到封闭的actor。不幸的是,还没有一种方法可以在编译时检测这些非法​​访问。

在 Actors 和 JMM 的文档中阅读有关它的更多信息”

于 2013-08-17T22:19:46.233 回答
2
  1. 好吧,我认为这id是按原样使用的。这是一个常数,不是吗?

  2. Victor Klang 给出了错误的来源: actor的sender方法访问。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")))
    }
    

    可以帮忙。

于 2013-08-18T17:47:45.440 回答
1

是的,应该

根据闭包的定义

于 2013-08-16T14:17:17.643 回答