我正在使用几个akka演员来监控我的系统,每个演员负责一个不同的组件.
一些演员操作不应该并行执行.所以我创建了一个持有锁(LockActor)的actor.一旦演员想要执行此类操作,他需要向LockActor请求批准,并且在获得批准之前他不能执行操作.
如果我想让代码变得简单,那么在请求的actor中我需要做类似的事情:
while (LockActor.isLockHold()) {
// perform the operation
}
Run Code Online (Sandbox Code Playgroud)
这当然打破了演员系统的整体设计......
所以我需要使用使代码有点复杂的消息:
所以我的问题是 - 什么是最好的方式实现这样的事情没有打破演员系统的设计,但仍保持代码尽可能简单?
而不是使用单个actor获取锁定,为什么不只使用单个actor来完成工作?这是actor模型中的首选方式.
我在这里看到两种解决方案。
首先,您可以使用询问模式:
class MyActor extends Actor {
def receive = {
case Start: {
val f = lockActor ? LockRequestMessage
f onSuccess {
case LockApprovalMessage => {
//todo: do your thing
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,ask 方法将创建另一个参与者,该参与者接收请求消息并完成 future - 有关更多详细信息,请参阅文档。
如果你不想使用ask模式,你可以很好地使用become-unbecome机制,如下所示:
class MyActor extends Actor {
import context._
def receive = {
case Start: {
lockActor ! LockRequestMessage
become(waitForApproval)
}
}
def waitForApproval = {
case LockApprovalMessage => {
//todo: do your thing
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以很好地在同一个接收函数中处理这两条消息,但您必须记录参与者在某个时刻所处的状态。“变得不合适”机制会为您完成这种干净的分离。
请注意,如果您使用锁来防止参与者改变某些共享资源,Akka 为此提供了一些更复杂的机制:
查看文档 - 它可能会显着简化您的实施。