如何在没有 Akka 的情况下实现 actor 模型? [英] How to implement actor model without Akka?

查看:36
本文介绍了如何在没有 Akka 的情况下实现 actor 模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在没有 Akka 的情况下实现简单的 actor?对于许多(非固定计数)actor 实例、绿色线程、IoC(生命周期、基于 Props 的工厂、ActorRef 的)、监督、背压等,我不需要高性能.只需要顺序性(队列)+ 处理程序 + 状态+ 消息传递.

作为一个副作用,我实际上需要基于actor的小型管道(带有递归链接)+一些并行actor来优化DSP 算法计算.它将在没有传递依赖关系的库中,所以我不想(并且不能因为它是一个 jar 插件)推动用户创建和传递 akkaSystem,该库应该具有简单和尽可能轻量级的界面.我不需要 IoC,因为它只是一个库(一组函数),而不是一个框架——所以它的算法复杂性比结构复杂.但是,我将 actor 视为描述协议的好工具,实际上我可以将算法分解为少量异步交互实体,因此它符合我的需求.

为什么不使用 Akka

Akka 很重,这意味着:

  • 这是一个外部依赖;
  • 具有复杂的接口和实现;
  • 对图书馆用户不透明,例如 - 所有实例都由 akka 的 IoC 管理,所以不能保证一个逻辑参与者总是由同一个实例维护,重启将创建一个新的;
  • 需要额外的迁移支持,这与 Scala 的迁移支持本身相当.
  • 使用 jstack/jconsole/jvisualvm 调试 akka 的绿色线程也可能更困难,因为一个参与者可能对任何线程进行操作.

当然,Akka 的 jar (1.9Mb) 和内存消耗(每 GB 250 万个演员)根本不重,因此您甚至可以在 Android 上运行它.但众所周知,您应该使用专门的工具来观察和分析参与者(如 Typesafe Activator/Console),这些用户可能不熟悉(我不会强迫他们学习).对于企业项目来说这一切都很好,因为它几乎总是有 IoC、一些专门的工具和持续迁移,但这对于一个简单的库来说并不是一个好方法.

附言关于依赖.我没有它们,我不想添加任何(我什至避免使用 scalaz,它实际上有点适合这里),因为它会导致大量维护 - 我将不得不保留我的简单库与 Akka 保持同步.

解决方案

这里是 JVM 世界中最精简、最高效的 actor,其 API 基于 Viktor Klang 的 Minimalist Scala actor:.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/src/test/scala/com/github/gist/viktorklang/Actor.scala

它使用起来方便且安全,但在消息接收方面不是类型安全的,并且不能在进程或主机之间发送消息.

主要特点:

有状态计数器示例:

 def process(self: Address, msg: Any, state: Int): Effect = if (state > 0) {println(msg + " " + 状态)自己 !留言成为{味精=>进程(自我,味精,状态 - 1)}否则死val actor = Actor(self => msg => process(self, msg, 5))

结果:

scala>演员!一种"一个 5标度>一个 4一个 3a21

How to implement simple actors without Akka? I don't need high-performance for many (non-fixed count) actor instances, green-threads, IoC (lifecycle, Props-based factories, ActorRef's), supervising, backpressure etc. Need only sequentiality (queue) + handler + state + message passing.

As a side-effect I actually need small actor-based pipeline (with recursive links) + some parallell actors to optimize the DSP algorithm calculation. It will be inside library without transitive dependencies, so I don't want (and can't as it's a jar-plugin) to push user to create and pass akkaSystem, the library should have as simple and lightweight interface as possible. I don't need IoC as it's just a library (set of functions), not a framework - so it has more algorithmic complexity than structural. However, I see actors as a good instrument for describing protocols and I actually can decompose the algorithm to small amount of asynchronously interacting entities, so it fits to my needs.

Why not Akka

Akka is heavy, which means that:

  • it's an external dependency;
  • has complex interface and implementation;
  • non-transparent for library's user, for example - all instances are managed by akka's IoC, so there is no guarantee that one logical actor is always maintained by same instance, restart will create a new one;
  • requires additional support for migration which is comparable with scala's migration support itself.
  • It also might be harder to debug akka's green threads using jstack/jconsole/jvisualvm, as one actor may act on any thread.

Sure, Akka's jar (1.9Mb) and memory consumption (2.5 million actors per GB) aren't heavy at all, so you can run it even on Android. But it's also known that you should use specialized tools to watch and analyze actors (like Typesafe Activator/Console), which user may not be familiar with (and I wouldn't push them to learn it). It's all fine for enterprise project as it almost always has IoC, some set of specialized tools and continuous migration, but this isn't good approach for a simple library.

P.S. About dependencies. I don't have them and I don't want to add any (I'm even avoiding the scalaz, which actually fits here a little bit), as it will lead to heavy maintenance - I'll have to keep my simple library up-to-date with Akka.

解决方案

Here is most minimal and efficient actor in the JVM world with API based on Minimalist Scala actor from Viktor Klang: https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/src/test/scala/com/github/gist/viktorklang/Actor.scala

It is handy and safe in usage but isn't type safe in message receiving and cannot send messages between processes or hosts.

Main features:

Example of stateful counter:

  def process(self: Address, msg: Any, state: Int): Effect = if (state > 0) { 
     println(msg + " " + state)
     self ! msg
     Become { msg => 
        process(self, msg, state - 1)
     }
  } else Die

  val actor = Actor(self => msg => process(self, msg, 5))

Results:

scala> actor ! "a"
a 5

scala> a 4
a 3
a 2
a 1

这篇关于如何在没有 Akka 的情况下实现 actor 模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆