Scala actor作为单线程队列

时间:2009-06-17 07:52:12

标签: scala message-queue actor concurrent-processing

我想在一个程序中使用actor,我会对某些演员有一些限制,好像他们是队列一样。例如,假设我有一些应用更改事件的外部系统,还有一些外部系统数据的缓存。所以我有两个演员:

  1. ChangeApplicationActor
  2. CacheActor
  3. 作为ChangeApplicationActor的一部分,当我将更改应用于外部系统中的某个实体X时,我想发送一些事件来告诉CacheActor同步:

    val changeApplicationActor = actor { 
      loop {
        react {
          case ChangeInstruction(x) => 
            externalSystem.applyChange(x)
            cacheActor ! Sync(x)
        }
      }
    }
    

    但我现在有两个要求:

    1. CacheActor有内部状态,理想情况下我希望它按顺序处理Sync指令
    2. 如果我最终收到CacheActor的收件箱,其中包含Sync(x)相同值的两条x说明,那么我想忽略第二个(即我应该对于任何给定的Sync}
    3. 值,只有一条待处理的x指令

      有没有办法强制演员单线程?有什么方法可以访问演员的邮箱并删除任何重复的事件?我不能避免将CacheActor as,嗯,不是演员来实现吗?

1 个答案:

答案 0 :(得分:5)

保证actor一次只在一个线程上执行,并且actor的邮箱中的消息按FIFO顺序排列,因此#1就在那里。

2比较棘手,因为它没有内置支持。演员有一个名为“邮箱”的属性。您可以直接访问邮箱,而不是通过接收或响应。在处理完邮件之前,您所要做的就是从邮箱中拨出匹配的同步邮件。执行此操作时,您必须在actor上进行同步,以防止另一个线程在发送消息期间尝试向邮箱添加内容。

应该注意的是,在actor上进行同步消除了库所做的死锁自由保证,并且会降低可伸缩性。但从实际的角度来看,你可能会没事。