1

我正在使用 Akka 和 scala。所以我在我的代码中调用 system.actorOf 或 context.actorOf 。但是,我正在包装 Akka 的库以创建演员,这样我就可以添加某些功能。因此,问题出现在如何允许我的更高级别抽象在任一上下文中工作。它们是在系统可用的环境中调用(在测试代码和应用程​​序的内核中),还是在参与者中调用(并且只能访问上下文变量)。

把它放在一起工作很容易。可以只创建一个函数,隐式获取上下文和系统,并根据可用的任何一个返回一个 ActorRef。然而,为了清除更多的重复,我遇到了一个问题。

还有许多其他地方我想自动访问范围内的任何地方(上下文或系统)。例如,如果我想调用 system.config 或 context.system.config,我需要为这种情况创建另一个包装函数。

我希望能够做这样的事情:

appropriate.actorOf(Props[Whatever], name = "breakfast")

并且适当的函数返回可用的任何一个(演员或系统),然后我会在两者之间有开关盒的每个地方使用这个函数。

我遇到的问题是,如果我从函数返回 Either[ActorContext, ActorSystem],我会收到一个错误,即 actorOf 在该类型上不可用。因此,它是根据类型检查它,而不是无论返回哪种类型都可以使用它。

有没有办法做我正在尝试的事情?

4

2 回答 2

0

对于发现此问题的其他人,这是我最终得到的解决方案:

def appropriateContext(implicit context: ActorContext = null, system: ActorSystem = null): ActorRefFactory = {
  val either: Either[ActorContext, ActorSystem] = if (context != null) Left(context) else Right(system)
  val refProvider = either.fold[ActorRefFactory](ac => ac, as => as)
  refProvider
}

然后我可以打电话

appropriateContext.actorOf(Props[Whatever])

这缺少我将添加的错误处理(如果两者都在范围内或都不在范围内该怎么办)但正在工作。

于 2013-11-07T17:42:36.890 回答
0

您应该使用子类型ActorRefFactory将其设为通用ActorContextActorSystem从其继承。您可以从确定要返回的类型的函数中返回它,也可以折叠Either您提到的:

  val either:Either[ActorContext, ActorSystem] = ...

  val refProvider =  either.fold[ActorRefFactory](ac => ac, as => as)

  refProvider.actorOf(Props[Whatever], name = "breakfast")

更新

要在评论中回答您的问题,首先,您正在创建一个Either对象,因此您不应该期望在其上有任何可用的内容方法。Either持有一个左或右对象,并且是一个具有自己方法的对象。foldover接受两个函数,Either一个接受左类型并返回新数据类型,另一个函数接受右类型并返回相同的数据类型。通过使用 fold,我们可以得到一个值。如果您想更深入地了解它是如何工作的,我强烈推荐使用Scala 中的函数式编程

此外,您可以简化代码并将它们全部删除,因为在您的上下文中确实没有必要:

  def appropriateContext(implicit context: ActorContext = null, system: ActorSystem = null): ActorRefFactory = {
    if (context != null) context else system
  }
于 2013-11-07T04:47:53.753 回答