Chu*_*mes 3 ruby concurrency erlang actor celluloid
从Joe Armstrong的论文中,他指出应该按照以下三个步骤设计一个基于Actor的程序.问题是,我不明白这些步骤如何映射到现实世界的问题或如何应用它们.这是乔的原始建议.
- 我们在现实世界活动中识别所有真正并发的活动.
- 我们识别并发活动之间的所有消息通道.
- 我们写下可以在不同消息通道上流动的所有消息.现在我们编写程序.程序的结构应该完全遵循问题的结构.每个真实世界的并发活动应该映射到我们的编程语言中的一个并发进程.如果问题的1:1映射到程序上,我们说该程序与问题同构.
映射恰好是1:1非常重要.这样做的原因是它最小化了问题和解决方案之间的概念差距.如果此映射不是1:1,程序将很快退化,并变得难以理解.当使用非CO语言来解决并发问题时,通常会观察到这种退化.通常,使程序工作的唯一方法是强制几个独立的活动由同一语言线程或进程控制.这导致不可避免的失去清晰度,并使程序受到复杂且不可重现的干扰错误.
我认为#1很容易弄明白.这是我迷路的#2(和3).为了说明我的挫败感,我在这个要点(带有回调的Ruby服务)中找到了一个小服务.
看看那个示例服务,我可以看到如何回答#1.我们有5个并发服务.
其中一些服务不起作用(或不起作用),具体取决于服务所处的状态.如果服务尚未启动,则登录/注销/订阅没有意义.这种状态信息与Joe的3个步骤有关吗?
无论如何,考虑到该要点中的示例/模拟服务,我想知道如何设计程序以Actory方式包装此服务.我想看一下如何应用Joe的3个步骤的指南列表.写一些代码(任何语言)的奖励积分.
通常,在构建应用程序以使用actor时,您必须识别应用程序的并发功能,这可能很棘手.您确定了5个并发"服务":
1,4和5似乎是可以流经系统的消息类型,2和3我不知道如何描述.你要点是相当大的,而不是超我清楚,但看起来你已经有了某种消息队列系统.用户可以采取的行动是:
我假设登录和退出需要一些身份验证步骤.我将进一步假设,如果用户未通过身份验证步骤,则他们的连接会中断,但创建连接的身份验证不充分.
系统采取的行动是:
如果这不是广泛的,请告诉我,我会改变这个答案.(我假定这会发送到用户的消息不会由用户生成的,但都是固有的一部分系统 ;也许我们讨论的监控服务.)总之,什么是并发吗?一些东西:
基于actor的体系结构将每个并发实体表示为其自己的进程.该用户是一个有限状态机进行认证,预订队列,或者接收消息和预订多个队列,并最终断开.在Erlang/OTP中,我们用gen_fsm来表示它.该用户进程进行与客户,如果我们在网络上公开服务,将是一个插座交互所需的所有状态.
身份验证意味着系统本身就是一个"进程",但实际上它更可能是Erlang/OTP中我们称之为应用程序的进程集合.我离题了.为简化起见,我们假设System本身就是一个单一的进程,它有一些定义明确的协议和一个保持用户凭据的状态.用户登录是的话,从一个明确定义的消息一个用户进程的系统过程和由其的响应.如果没有身份验证,我们就不需要系统进程,因为与用户相关的唯一状态是套接字.
细心的读者会问我们在哪里接受每个用户的套接字连接?啊,好问题.还没有提到另一个并发实体,我们在这里称之为Listener.这是另一个只监听连接的进程,为每个新建立的套接字创建一个User,并将所有权移交给新的User进程,然后循环回来监听.
该队列也是有限状态机.从其开始状态开始,它通过明确定义的协议接受用户订阅请求,向订阅者广播消息或接受来自用户进程的取消订阅请求.这意味着Queue具有User进程的内部存储,其细节非常依赖于语言和需求.例如,在Erlang/OTP中,每个队列进程都是gen_server,它将用户进程ID(或PID)存储在列表中,并且每个要传输的消息只需对列表中的每个用户进程执行多次发送.
(在Erlang/OTP中,我们的用户主管确保进程保持活动并在死机时重新启动,这极大地简化了Erlang开发人员为确保基于actor的架构的可靠性而必须完成的工作量.)
基本上,为了重述Joe所写的内容,基于actor的架构归结为以下几点:
有人说,互联网是世界上最成功的基于演员的架构,而且,实际上,这并不遥远.
| 归档时间: |
|
| 查看次数: |
293 次 |
| 最近记录: |