加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何在没有Akka的情况下实现actor模型?

发布时间:2020-12-16 09:00:24 所属栏目:安全 来源:网络整理
导读:没有Akka如何实现简单的演员?对于许多(非固定计数)actor实例,绿线程,IoC(生命周期,基于Props的工厂,ActorRef),监督,背压等,我不需要高性能.只需要序列性(队列)处理程序状态消息传递. 作为一个副作用我实际上需要基于演员的小管道(带递归链接)一些并行演员来
没有Akka如何实现简单的演员?对于许多(非固定计数)actor实例,绿线程,IoC(生命周期,基于Props的工厂,ActorRef),监督,背压等,我不需要高性能.只需要序列性(队列)处理程序状态消息传递.

作为一个副作用我实际上需要基于演员的小管道(带递归链接)一些并行演员来优化DSP算法计算.它将在没有传递依赖的库内部,因此我不希望(并且不能因为它是一个jar-plugin)推动用户创建和传递akkaSystem,库应该具有尽可能简单和轻量级的接口.我不需要IoC,因为它只是一个库(一组函数),而不是一个框架 – 因此它具有比结构更多的算法复杂性.但是,我认为actor是描述协议的好工具,我实际上可以将算法分解为少量的异步交互实体,因此它符合我的需要.

为什么不Akka

Akka很重,这意味着:

>这是外部依赖;
>具有复杂的界面和实现;
>例如,库的用户不透明 – 所有实例都由akka的IoC管理,因此无法保证一个逻辑actor始终由同一个实例维护,重启将创建一个新的;
>需要额外的迁移支持,这与scala的迁移支持本身相当.
>使用jstack / jconsole / jvisualvm调试akka的绿色线程也可能更难,因为一个actor可能会对任何线程起作用.

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

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

解决方法

这里是JVM世界中最简单高效的演员,其基于来自Viktor Klang的极简主义Scala演员的API:
https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/src/test/scala/com/github/gist/viktorklang/Actor.scala

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

主要特点:

>最简单的FSM类API,仅有3种状态(Stay,Become and Die):https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/src/test/scala/com/github/gist/viktorklang/Actor.scala#L28-L30
> minimalistic错误处理 – 只需正确转发到执行程序线程的默认异常处理程序:https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/src/test/scala/com/github/gist/viktorklang/Actor.scala#L52-L53
>快速异步初始化需要大约200 ns来完成,所以不需要额外的期货/演员来进行耗时的演员初始化:https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/out0.txt#L447
>最小的内存占用,即处于被动状态的~40字节(BTW新的String()在JVM堆中花费相同的字节数):https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/out0.txt#L449
>消息处理效率非常高,4核CPU的吞吐量约为90M msg /秒:https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/out0.txt#L466
>在消息发送/接收方面非常有效,延迟~100 ns:https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/out0.txt#L472
>每个演员通过批处理参数调整公平性:https://github.com/plokhotnyuk/actors/blob/41eea0277530f86e4f9557b451c7e34345557ce3/src/test/scala/com/github/gist/viktorklang/Actor.scala#L32

有状态计数器的示例:

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,5))

结果:

scala> actor ! "a"
a 5

scala> a 4
a 3
a 2
a 1

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读