当前位置: 首页 > 知识库问答 >
问题:

懒惰地创建Akka演员等级

徐峰
2023-03-14

我想创建可以从文件系统中为资源服务的参与者。理想情况下,[1]我希望每个目录和每个文件都有一个参与者。但是我不想创建整个actor树层次结构,因为我希望尽可能节省内存和资源。

据我所知,只有当它的父级存在时,才能创建一个演员。懒洋洋地创建这些层次结构的最佳方法是什么。是否有一个钩子可以用来捕捉失败并在飞行中创建参与者层次结构,并有效地这样做?

这样,我就可以向参与者发送fetchupdatedelete、...消息,从而使akka参与者系统能够处理同步问题。这可以扩展到更复杂的演员行为,后来有了虚拟文件或类似的概念...

    null

共有1个答案

仇正平
2023-03-14

第一,演员非常轻量级。您可以在一个JVM中运行数百万个参与者,而参与者本身的占用空间非常小。很明显,如果参与者有一些自定义状态,这会发生变化,而参与者本身的占用空间非常小。

现在,如果您仍然想要懒洋洋地实现它们,一种方法可能是使用一个单一的文件或文件夹主执行元来接收所有的初始调用。此参与者检查系统,以查看是否已经存在参与者来为请求所针对的文件夹或文件的请求提供服务。如果没有,主控器创建它,然后将消息转发给它。如果是,它只是将消息转发给它。无需在内存中保存hashmap,因为ActorSystem本身将为您保存所有ActorRefs并为您提供查找它们的方法。您只需要一个将文件名/路径等同于参与者名称的方法。一个过于简化的主程序示例可能如下所示:

case class Fetch(path:String)
class FileMaster extends Actor{
  def receive = {
    case msg @ Fetch(path) =>
      val ref = lazyFindActor[FileHandler](path)
      ref.forward(msg)
  }

  def lazyFindActor[T <: Actor: Manifest](name:String) = {
    val ref = context.actorFor(name)
    if (ref == context.system.deadLetters){
      context.actorOf(Props[T], name)
    }
    else{
      ref
    }
  } 
}

LazyFindActor所做的就是检查路径的actor是否已经创建和启动。如果是,它转发给它。如果没有(它与deadletters进行比较,以确定是否存在参与者,因为不幸的是,我没有看到更好的方法来检查参与者是否存在),它在主程序的监督下创建一个参与者,然后转发给它。下次同样的路径进入时,它将使用预先存在的执行元

 类似资料:
  • 让我们假设一个使用Akka Typed实现的应用程序有一个持久执行元。这个持久执行元作为其操作的一部分创建了瞬态(或非持久)子执行元,每个子执行元都有一个唯一的ID,这些ID是持久状态的一部分。持久执行元还需要一些与其子级通信的方式,但我们不希望持久化子级的,因为它们实际上不是状态的一部分。在恢复时,持久参与者应该基于恢复的状态重新创建它的子级。这听起来并不像是一个很不寻常的用例,我正在试图弄清楚

  • 我对阿克卡很陌生,我有一个(希望)简单的问题。我有一个参与者需要重复执行某个小的子任务——也就是说,每次这个参与者收到消息时,它都必须执行N个子任务。这个子任务是我指定给儿童演员的。我的问题是,我是否应该为每个子任务创建一个新的子角色实例?或者我应该简单地产生一个孩子演员,并发送N条消息?在这种情况下,最好的做法是什么? 为了更好地说明我的问题,这里有两个简化的示例(在Java中-但希望对Scal

  • 问题内容: 我正在尝试使用ActorFor获取现有的ActorRef,或者如果不存在则创建一个新的。我有以下代码,但它似乎没有按预期工作。.isTerminated()始终为true。 我在这里想念什么?提前致谢。 问题答案: “获取或创建”只能由指定的actor 的 父级 执行,因为只有该父级可以创建actor(如果不存在),并且只有父级才能一致地创建(即没有竞争条件)。在演员中,您可以做 不要

  • 我正在尝试使用ActorFor获取现有的ActorRef,或者如果它不存在,则创建一个新的ActorRef。我有以下代码,但它似乎没有按预期工作。isTerminated()总是正确的。 我错过了什么?提前谢谢。

  • 我正在将现有应用程序从Akka Classic移植到Akka Typed。最初,您可以使用上下文获取对参与者的引用。actorSelection()。resolveOne() 我知道在Akka Type中不再支持这一点,我们应该使用来注册演员以供发现。 但是,我只想将消息发送到本地参与者,即存在于集群中每个节点上的本地单例。我有它的本地路径,但没有对它的直接引用。这是因为它是由Akka管理系统创建

  • 我很想知道调整大小,或者在本例中增加单个节点系统上的actor池中actor的数量是否真的会影响性能。 我有一个带超线程的四核系统。在任何给定的点上,系统可以运行8个线程。假设执行元执行的大多数操作都是CPU绑定的,那么将池中的执行元数量从20个增加到40个会有什么收获呢?