2013-10-17 52 views
0

我目前每秒向Akka actor发送消息以执行任务。避免同时执行Akka actor

如果该任务(功能)在演员收到新消息时仍在运行,我希望演员什么也不做。基本上,我希望演员功能只在未运行时才能运行。

这样做的好方法是什么?我应该使用阿卡演员还是以另一种方式做?

干杯

+1

如果函数在actor中同步运行,它已经表现得如此。它有一个消息框,并且一次只能处理一条消息。 – drexin

+0

@drexin不完全。这个问题似乎意味着如果演员很忙,应该放弃这个信息。 (但是这对于演员来说是一个糟糕的用例,演员不需要花费相当长的时间来处理消息。) –

+0

@Blackbird如果actor已经在处理一些消息,你想要防止干扰新的消息处理?或者,您想在新消息到达时暂停/中止当前处理? –

回答

1

参与者一次处理消息。你描述的情况不会发生。

+0

但是,如果处理此类消息超过1秒钟,OOME可能会发生邮箱溢出。 –

+0

@SergiyPrydatchenko,除非你使用有界的邮箱,不是? –

+0

@ om-nom-nom当然,如果发件人线程阻塞对您的应用程序可用,您可以使用有界的邮箱。 –

0

阿卡演员异步一个接一个处理他们的消息,所以你只能丢弃/忽略“失效”的消息,以避免额外的处理和OutOfMemoryException异常-S由于演员的邮箱溢出。

可以忽略过期(在你的案件超过1秒左右)的消息您的演员里面:

case class DoWork(createdTime: Long = System.currentTimeMillis) 

final val messageTimeout = 1000L // one second 

def receive = { 
    case DoWork(createdTime) => 
    if((System.currentTimeMillis - createdTime) < messageTimeout) { doWork() }  
} 

或者,您可以创建自定义邮箱,可以在内部丢弃过期的消息。

当然,正如罗宾格林已经提到的,一般演员不应该在内部运行长时间运行的操作,所以这种方法只有在您的演员不需要处理其他类型的消息时才适用(他们不会及时处理)。并且在CPU需求较高的情况下,您可能会考虑将您的演员移动到单独的调度器上。

+0

我不明白你的意思是“已过期”的信息,对不起。 – Blackbird

+0

如果您每隔一秒向演员发送一条消息,并且如果您的演员从其邮箱中收到了一秒多前已发送(创建)的邮件,则这意味着此邮件已存储在邮箱中超过一秒钟(而你的演员忙于处理前一个) - 所以你可以放心地丢弃这个消息(如果它当然不包含重要数据),并等待下一个应该在一秒钟内收到的消息。 –

+0

你确定这种方法适用于* remote * actors吗? –