我想在一个程序中使用actor,我会对某些演员有一些限制,好像他们是队列一样。例如,假设我有一些应用更改事件的外部系统,还有一些外部系统数据的缓存。所以我有两个演员:
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
指令
醇>
有没有办法强制演员单线程?有什么方法可以访问演员的邮箱并删除任何重复的事件?我不能避免将CacheActor
as,嗯,不是演员来实现吗?
答案 0 :(得分:5)
保证actor一次只在一个线程上执行,并且actor的邮箱中的消息按FIFO顺序排列,因此#1就在那里。
2比较棘手,因为它没有内置支持。演员有一个名为“邮箱”的属性。您可以直接访问邮箱,而不是通过接收或响应。在处理完邮件之前,您所要做的就是从邮箱中拨出匹配的同步邮件。执行此操作时,您必须在actor上进行同步,以防止另一个线程在发送消息期间尝试向邮箱添加内容。
应该注意的是,在actor上进行同步消除了库所做的死锁自由保证,并且会降低可伸缩性。但从实际的角度来看,你可能会没事。