Scala actor作为单线程队列

oxb*_*kes 2 scala message-queue concurrent-processing actor

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

  1. ChangeApplicationActor
  2. CacheActor

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

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

但我现在有两个要求:

  1. CacheActor具有内部状态和理想,我想它来处理其Sync指令顺序
  2. 如果我最终收到CacheActor包含两个Sync(x)相同值的指令的收件箱x,那么我想忽略第二个Sync指令(即我应该只有一个挂起的指令用于任何给定的值x)

有没有办法强迫演员单线程?有什么方法可以访问演员的邮箱并删除任何重复的事件?难道我不能避免实施CacheActoras,嗯,不是演员吗?

Eri*_*cht 5

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

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

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