演员模型:一个演员需要另一个演员的信息



我对演员模型不了解的东西。假设你有两个演员。他们从各种来源收集和管理数据。这些来源通过其收件箱/邮箱/队列与演员互动。例如,演员A收集信号,而演员B则管理整个系统的信息。

在某个时候,Actor A必须处理其数据。在处理过程中,它不能做太多其他事情。例如,无法处理新信号。作为数据处理的一部分,Actor A需要来自Actor B的信息。

在伪代码中:

functionOfActorA()
{
  internalQueue {
   ...doing stuff with our data
   info = actor_B.getInfo() -> what should happen here?
   ...doing stuf with our data and the obtained info
   }
}
getInfo()//function of actor B
{
  internalQueue {
    ...prepare requested info
    ... -> what should happen here?
  }
} 

如果两个演员都应以自己的队列或线程独立运作,那么您如何应演员的要求将信息从一个演员到另一个演员?

Actor A可以通过向Actor B发送请求来请求信息,但是响应将在一条消息中返回,该消息将在以后的某个时间点收到。有两种保存此信息的方法:

  1. 演员A可以在内部存储信息以等待该响应。

  2. 演员A可以将信息附加到它发送给Actor B的消息,而Actor B则返回该上下文(否则它忽略)。

当演员A从演员B中获取信息时,它可以恢复处理。

这是使用Thespian Python Actor库(http://thespianpy.com)的第一种实施方式的示例:

class ActorA(Actor):
    def __init__(self, *args, **kw):
        super(ActorA, self).__init__(args, kw)
        self.datalist = []
    def receiveMessage(self, msg, sender):
        if isinstance(msg, ActorAddress):
            self.actorB = msg
        elif isinstance(msg, WorkRequest):
            x = got_some_data(msg)
            self.datalist.append(x)
            self.send(self.actorB, NeedInfo())
        elif isinstance(msg, Info):
            x = self.datalist.pop()
            process_data(x, msg)
class ActorB(Actor):
    def receiveMessage(self, msg, sender):
        if isinstance(msg, NeedInfo):
            i = get_info(msg)
            self.send(sender, i)

以上显示了将工作内部存储给演员的基本功能,以后将继续进行。有一些考虑因素:

  • 如果要存储多个数据项,则Actora需要某种方法来确定来自Actorb的信息适用于。

  • Actora需要处理尚不知道Actorb地址的情况。

  • Actora可能应该使用某种超时来避免将工作永久保存在其内部列表上(如果Actorb永远不会响应)。

  • 如果Actora退出或死亡,它应该在退出之前对数据师的项目做适当的事情。

这是第二个实现样式的相应简单示例:

class ActorA(Actor):
    def receiveMessage(self, msg, sender):
        if isinstance(msg, ActorAddress):
            self.actorB = msg
        elif isinstance(msg, WorkRequest):
            x = got_some_data(msg)
            self.send(self.actorB, NeedInfo(x))
        elif isinstance(msg, Info):
            x = msg.orig_request.data
            process_data(x, msg)
class ActorB(Actor):
    def receiveMessage(self, msg, sender):
        if isinstance(msg, NeedInfo):
            i = getinfo(msg)
            i.orig_request = msg
            self.send(sender, i)

在第二个示例中,创建needInfo的调用将数据存储在需求info对象的.data字段中,而Actorb传递的信息则附加了原始的NeedInfo消息。此样式的考虑因素是:

  • Actora更依赖Actorb的实施,期望Actorb将原始消息附加到其响应中,以允许Actora恢复此上下文。

  • Actora仍然需要处理尚不知道Actorb地址的情况。

  • 如果Actora退出或死亡,那么在清理之前采取任何措施没有记录的记录(尽管死了字母处理者可以执行此角色)。

上面的示例非常简单,其他Actor模型库实现将有一些变化,但是这些通用技术应大致应用,无论库/语言如何。这两种实施方式都遵循:

的一般参与者指南。
  1. 收到消息时,请执行可能的工作

  2. 根据需要更新内部状态以处理下一个消息

  3. 从消息处理程序退出

虽然可以写一个执行阻止操作的演员,但该操作将干扰演员的响应能力和处理其他消息的能力(如您正确指出),因此,只要可能使用消息驱动的延续,而不是阻止呼叫。

相关内容

  • 没有找到相关文章

最新更新