Akka演员返回不同类型的输出

时间:2015-07-31 13:31:18

标签: scala generics akka

我有一个在scala中使用Akka Actors的项目,我遇到了一些有关处理器的问题并将结果发送回发件人。

为了更好地解释,这是我的项目具有的工作流程

  • 指挥官将消息发送给Poller
    • Poller将SuccessMessage(self,List [String])发送给Commander
  • Commander将List [String]发送给处理器
    • 处理器将SuccessMessage(self,File)发送给Commander
  • Commander将文件发送给上传器
    • Uploader将SuccessMessage(self,Boolean)发送给Commander
  • 等等。

基本上,我有两个问题:

现在,我将从演员返回的所有内容包装回SuccessMessage中的Commander(主管)。这是最好的方式吗,还是有另一种方式来处理许多不同类型的回报?

SuccessMessage还将具有“有效负载”。我正在讨论在有效载荷类型中使用泛型,或者只是将它作为Option [Any]然后在指令器端进行大量的转换,然后再将其发送给任何actor(轮询器,处理器等)。我知道在Java中akka actor只是强制转换Object;我必须这样做吗?

2 个答案:

答案 0 :(得分:2)

没有“正确”的方式,但我就是这样做的:

使每个actor类型对的消息都是唯一的。将实际数据包含在以下消息中:Poll(something)Polled(result)Process(something)Processed(result)Upload(something)Uploaded(result)

然后发送PollFailed(details)ProcessingFailed(details)UploadFailed(details)消息,或将Option放入正常结果消息中。我喜欢使用Option

我会在PollerProcesserUploader的配套对象中定义这些消息。

指挥官的接收方法非常漂亮:

def receive = {
  case Polled(Some(result)) => // handle
  case Polled(None) => // handle
  case Processed(Some(result)) => // handle
  case Processed(None) => // handle
  case Uploaded(Some(result)) => // handle
  case Uploaded(None) => // handle
}

远离泛型。由于类型擦除,您无法在接收方法中匹配泛型。

答案 1 :(得分:1)

我还没有看到你的代码,但我建议做两件事:

  1. 为成功创建不同类型的消息。 E.g。

    • MessagesPolled(List[String])
    • MessagesProcessed(File)
    • MessagesUploadedMessagesNotUploaded(Error)

    通过这种方式,您的逻辑将被划分为正确的,并且连接到每条消息的逻辑将保存在不同的位置(以后可以在不影响其他逻辑的情况下进行更改)。

  2. 创建演员的层次结构,使每个演员都负责一件事(包括顶级演员),例如:

    • Commander引用了三个actor(拥有自己的worker hierarchies):
      • Poller仅将消息路由到动态创建的PollerWorker s
      • Processor仅将消息路由到动态创建的ProcessorWorker s
      • Uploader仅将消息路由到动态创建的UploaderWorker s
    • Commander收到一条触发消息,并向Poller发送第ActorRef条消息给nextStepActor ProcessorWorker,如果是第一条消息,则为{{1} }}

    通过这种方式,您可以将逻辑封装在不同的actor中,轻松扩展,而不是压倒Commander actor。