我想在程序中使用参与者,在该程序中我会对将某些参与者视为队列进行某种限制。例如,假设我有一些应用更改事件的外部系统以及外部系统数据的一些缓存。所以我有 2 个演员:
ChangeApplicationActor
CacheActor
作为
ChangeApplicationActor
的一部分,当我对外部系统中的某个实体 X
应用更改时,我想发送一些事件来告诉 CacheActor
进行同步:
val changeApplicationActor = actor {
loop {
react {
case ChangeInstruction(x) =>
externalSystem.applyChange(x)
cacheActor ! Sync(x)
}
}
}
但我现在有两个要求:
CacheActor
具有内部状态,理想情况下我希望它按顺序处理其 Sync
指令CacheActor
的收件箱,其中包含两个 Sync(x)
相同值的 x
指令,那么我想忽略第二个(即,我应该只有一个待处理的 Sync
指令)对于任意给定值 x
)有什么方法可以强制 Actor 成为单线程吗?有什么方法可以访问演员的邮箱并删除任何重复的事件吗?我能否避免将
CacheActor
实现为,嗯,不是演员?
一个 Actor 保证一次只在一个线程上执行,并且 Actor 邮箱中的消息是按 FIFO 顺序排列的,所以 #1 就在那里。
2 比较棘手,因为没有内置支持。 演员有一个名为“邮箱”的属性。 您可以直接访问邮箱,而不是通过 receive 或 React 来访问。 您所要做的就是在处理完消息之前将匹配的同步消息从邮箱中拉出。 执行此操作时,您必须在参与者上进行同步,以防止另一个线程在消息发送期间尝试将内容添加到邮箱。
应该注意的是,在 Actor 上进行同步消除了库所做的死锁自由保证,并且会降低可扩展性。 但从实际角度来看,你可能没问题。