react编程式路由_React式编程虚拟小组

react编程式路由

响应式编程是一个非常热门的话题:用于构建响应式系统的库在许多平台和语言上如雨后春笋般冒出。 诸如响应式宣言 (观看FranceQ Cesarini和Viktor Klang的InfoQ访谈)之类的倡议正在推广这一想法,并且借助响应式流 (也请参见InfoQ上的响应式流与Akka流 ),甚至在努力提供响应式库之间的互操作性。

但是React是什么意思呢? 实现之间有何不同? InfoQ在虚拟小组中汇集了React式编程的三个支持者,以找出并了解有关各个项目的更多信息。

注意:我们可能错过了喜欢的库来处理数据流和其他React性用例。 在评论中告诉我们您希望看到哪些其他库(以及可以联系的好的面板参与者),我们将尝试为该虚拟面板编写一个续集。

参与者们:

Viktor Klang是Typesafe的首席架构师,也是Akka项目负责人。

Timothy Baldridge是Cognitect和Core.Async提交者的Clojure开发人员。

Jafar Husain是Netflix的技术主管,并为RxJava做出了贡献。

我们要求他们回答以下问题:

  1. 请简要介绍您的库或框架。
  2. 您如何实现React性/并发性? 它建立在什么原始,概念或语言构造上? 程序员可以控制代码的执行方式或处理背压吗?
  3. 它如何与平台的功能集成,即I / O库,集合,可用算法等?
  4. 与您的语言中的其他方法相比,您的解决方案为什么更好? 它主要是防止错误,降低障碍或启用新的编程风格吗?
  5. 对于什么样的问题,图书馆是最好的解决方案,或者实施它的最初动机是什么? 您什么时候会使用其他东西?
  6. 我需要重新考虑编程方式吗? 也就是说,有没有限制,我可以只使用纯函数吗,我可以将所有内容包装在monad中还是必须通过延续?
  7. 您的编程语言或平台是否会带来任何好处,或者是否使事情变得复杂或完全不可能? 您想分享一些特殊的实施挑战吗?

InfoQ:请向我们简要介绍您的库或框架。

Viktor Klang: Akka是JVM(主要是Java和Scala,但存在到JRuby,Clojure等的绑定)上的Reactive应用程序的库和运行时,它使用Actor(请参阅Actor模型 )作为并发的主要构造; 分配; 弹性; 并从小型设备扩展到大型服务器,从单个节点扩展到群集中的数千个节点。
Timothy Baldridge Core.Async是一个库,可在Clojure(在JVM上)和ClojureScript(在JavaScript VMs)上启用CSP( 通信顺序过程 )样式编程。 顾名思义,这是将代码组织为通过通道进行通信的逻辑线程的一种方式。 考虑CSP的一种好方法是生产装配线。 执行的逻辑线程是工人,而队列为工人提供了用于交流的传送带。
Jafar Husain: Rx提出了一个问题: 事件与集合(如数组或集合)之间有什么区别? 今天,大多数开发人员针对事件和集合进行编程的方式都非常不同。 Rx为您提供事件和集合的统一编程模型。 该库使您可以像处理集合一样使用事件,并使用map,filter和reduce等函数对其进行转换。 无需构建状态机来响应事件序列,而是使用这些方法从简单事件创建复杂事件。

InfoQ:您如何实现React性/并发性? 它建立在什么原始,概念或语言构造上? 程序员可以控制代码的执行方式或处理背压吗?

Timothy Baldridge:该代码被组织成逻辑线程。 这些线程是否可以与OS线程进行1:1映射,这取决于程序员。 逻辑线程之间的通信是通过称为队列的阻塞队列进行的。 这些渠道提供了反压力,并支持同一渠道上的多个读者和作家。 由于该模型的简单性,可以很容易地根据需要扩展到更高级别的并行性,只需分配更多逻辑线程即可读取或写入同一通道。
Jafar Husain: RX引入了一种新的收集类型:Observable。 Observable类似于UI元素上的事件,但是Observable是一流对象,可以像List或Set一样传递。

像事件一样,您可以为Observable订阅回调,并在数据异步到达时得到通知。 但是,Observable将完成的概念添加到事件流中。 这种简单的添加使开发人员可以构建复杂的事件驱动系统,而不必显式取消订阅。

通常,在构建诸如用户界面之类的长期应用程序时,必须小心地取消订阅事件,以避免内存泄漏。 即使事件不再触发它们,事件也将保留在处理程序中(例如,“ document.onload”在加载网页DOM时触发)。 相反,当可观察数据流完成时,处理程序将自动退订。

您可以使用计划程序来控制何时进行操作。 调度程序控制Observable何时何地通知您数据已到达。 调度程序可以确保订阅或通知在特定时间段后发生在不同的线程或同一线程上。

例如,您可以通过调度两个可观察对象在线程池上运行来并行执行它们。 在JS之类的单线程环境中,可以使用调度程序在事件循环的关键时刻观察事件流,

关于背压,始终可以从Observable退订以阻止数据流,然后在以后重新订阅。 当前正在探索更复杂的方法,您可以期望在以后的Rx版本中看到它们。
Viktor Klang:如前所述,主要的抽象是Akka Actors(“ Actors”),它是Actor模型的JVM实现。 一个Actor在逻辑上与其他Actor隔离,这意味着Actor在称为ActorSystem(Actor的逻辑层次结构)内相互并发运行。

Actor的核心是一种行为,它适用于其传入消息,您可以通过向Actor发送消息,然后一次处理一个消息,与Actor进行通信。 在处理消息时,它可以决定:创建新的Actor; 向其知道的演员发送消息; 更改其处理的下一条消息的行为; 或这些动作的任意组合。 Actor的创建和向其发送消息两者都是异步执行的。 这意味着Actor本质上是事件驱动的。

演员具有:
  • 创造它的“父母”演员
  • 一种行为,它将应用于它处理的下一条消息
  • 一个忙于处理入站邮件的邮箱
  • 负责协调执行者执行的分派器
  • 它创建的0..N个“子”演员

Actor是一个非常轻量级的结构(通常重约450个字节),这意味着您可以在商品硬件上同时运行数百万个。

执行
Actor的执行(将消息应用于行为)由Akka Dispatchers完成,通常由ExecutorService支持。 所有这些都可以由程序员配置-既可以通过编程方式也可以通过配置从外部进行配置。 实际上,大多数事情都是程序员可配置和可自定义的:邮箱实现,ExecutorServices,Dispatchers等。

背压
反压是通过Acking / Naking入站消息实现的-这意味着非阻塞的异步反压。

弹性
抵御能力是通过一种称为“监督”的方法来实现的,在该方法中,Actor内部引发的异常会升级为该Actor的父级,而对有故障的Actor的执行将被挂起,直到父级决定如何处理故障为止。 以下结果是可能的:

  • 恢复(忽略故障,并为失败的参与者恢复处理消息)
  • 重新启动(丢弃发生故障的actor的旧实例,并创建一个新实例,保持邮箱不变)
  • 停止(终止失败的演员)
  • 升级(重新引发故障,将问题升级为“祖父母”)

该主管层次结构意味着Actor可以创建新的Actor来执行可能具有风险的操作,然后使用Supervision来处理任何故障,而不会使其面临风险。 这通常称为“ 错误内核模式 ”。

有趣的是,由于消息驱动的特性与故障检测器相结合,当层次结构分布在多个节点上时,这也适用。

一种常见的模式是让一组Actor使用不同的Dispatchers和ExecutorService隔离执行,因此,如果一组运行amok,则其他组不受影响。 这通常被称为“隔板”。

InfoQ:它如何与平台的功能集成,例如I / O库,集合,可用算法等?

Jafar Husain: Observable实现了大多数集合转换功能,这些功能将在Java 8的新Stream类型,C#的Enumerable类型和Javascript的Array类型中找到。 如果您知道如何使用诸如map,filter和reduce的功能来转换集合,则可以轻松地用Rx构建复杂的异步程序。

Rx提供了辅助方法,可将任何异步接口转换为Observable。 这样可以轻松地将Rx逐渐集成到任何现有程序中。 您可以从小规模开始,对系统中事件的子集使用组合,然后逐步扩展它。
Viktor Klang: Akka有一个IO库,它建立在Java的NIO功能之上,该功能将IO公开为简单而熟悉的消息传递:发送和接收数据块。

对于集合,您可以随意在Actor中使用任何内容,但是在发送包含集合的消息时,强烈建议您发送不可变的集合。

除此之外,您可以使用您选择的任何JVM库。
Timothy Baldridge: Java和JavaScript虚拟机上的大多数平台库都支持通过回调进行异步。 在最低级别,Core.Async通道使用相同的模型。 因此,从主机VM进行回调以将项目放入通道中很容易,而附加到通道的回调则调用某些VM方法非常容易。

InfoQ:与您的语言中的其他方法相比,您的解决方案为什么更好? 它主要是防止错误,降低障碍或启用新的编程风格吗?

Viktor Klang: Actor是一个通用结构,它统一了并发,分发和故障管理,从而可以上下扩展和内向外扩展。 对于更专业的用例,诸如FuturesAgents等其他工具可能会派上用场。
Timothy Baldridge:通常,当应用程序达到一定大小时,程序员将创建分布式队列,以将程序分解为更小,更易于管理的部分。 该模型还为可伸缩性提供了更多选择,因为程序员可以根据需要将读取器和写入器的数量调整到队列中,以提高性能。

必须问他们一个问题,为什么我们从一开始就不这样构建系统? 为什么不通过将应用程序设计为在进程内队列之间通信的逻辑线程集来从高度解耦的系统开始。 然后,当需要扩展我们的应用程序时,我们可以开始用分布式队列替换这些进程内队列。

用这种方式构建的系统通常更易于调试,因为在通过通道将其连接到其他组件之前,可以单独测试每个组件。
Jafar Husain: Rx易于学习,因为它利用了开发人员关于如何使用诸如map,filter和reduce的转换功能来组成集合的现有知识。 实际上,最困难的部分是无法了解事件与您每天已经使用的集合有所不同的想法。

RX还可以帮助开发人员避免常见的陷阱,例如内存泄漏。 在构建传统的基于事件的系统时,开发人员通常依赖状态机来确定何时取消订阅事件。 Rx允许您构建事件流,以声明方式指定结束事件的条件。 事件流结束后,它将为您清除所有未完成的订阅。

InfoQ:对于什么样的问题,图书馆是最好的解决方案,或者实施它的最初动机是什么? 您什么时候会使用其他东西?

Timothy Baldridge Core.Async在程序需要以异步方式与其他系统交互的系统中非常成​​功。 这些系统可以是外部排队服务,数据库,甚至是HTML DOM。 但是,此模型确实会引入少量开销。 因此,当唯一的目标是并行性时,使用此库可能是不明智的。 例如:我不会使用core.async来构建3D raytracer。 如果您遇到同步且令人尴尬的并行问题,则可以使用更好的选择。
Jafar Husain: Rx的想法来自Erik Meijer和Brian Beckman注意到Iterator模式和Observer模式之间的基本对应关系。 每种模式都使数据生产者可以一次将数据逐步发送给数据消费者。 不同之处在于,在迭代器模式下,消费者处于控制权中,从生产者中提取数据,而在观察者模式中,生产者处于控制权中,将数据推送给消费者。

Erik和Brian注意到观察者模式中的一个奇怪的遗漏。 在Iterator模式中,生产者可以使用明确定义的方式向消费者发出数据序列已结束的信号,但是在Observer模式中,则没有这种语义。 例如,对于DOM事件,没有明确定义的方式来通知消费者不再有数据到达。

Erik和Brian意识到,只要将完成的概念简单地添加到Observer模式中,这两种无处不在的设计模式就可以统一。 结果是一种新类型:可观察的。 这两种类型都是对偶的,这意味着还可以为Observable定义可用于组成Iterable的任何运算符。 这意味着可以像数据库一样查询事件流。
Viktor Klang: Akka由JonasBonér创建,目的是将很多来自Erlang的美好事物带入JVM中-特别是具有独立的“进程”,这些进程通过消息进行通信并通过监督来处理故障。

Akka背后的一个驱动原理是所有基本操作都是位置透明的,这意味着Actor的位置无关紧要,以结束其消息或对其进行监督。 这使Akka成为在多台机器上分布应用程序的理想工具,既可以提高处理能力,又可以提高弹性。

InfoQ:我需要重新考虑编程方式吗? 也就是说,有没有限制,我可以只使用纯函数吗,我可以将所有内容包装在monad中还是必须通过延续?

蒂莫西·鲍德里奇(Timothy Baldridge):幸运的是,不需要单子或连续通过。 通过代码重写宏支持Core.Async中的轻量级线程。 库的用户只需将他们的代码包装在一个“ go”块中,其余的由宏完成。 将代码重写为附加到通道的回调。 这是该库最强大的功能之一,它允许程序员编写看起来像他们每天编写的命令式代码的代码。

确实需要考虑的一个方面是关于IO的问题。 该库将OS线程支持的逻辑线程与非OS线程支持的逻辑线程区分开。 这两种类型的线程可更好地完成不同的任务。 专用线程通常用于IO,而轻量级线程则建议用于CPU密集型任务。
维克多·巴生(Viktor Klang):我首先要说的是,通过开始考虑交流(即在Actor之间流动的消息协议)来改变编程方式。
一种快速而有趣的方法是考虑如何与人一起解决问题,因为人类可以通过相互发送消息(无论是电子邮件,口头语言,即时消息还是其他方式)相互协调。 我们不会直接翻转他人的神经元! (与共享内存并发进行比较。)
另一个有趣的变化是您现在如何开始将体系结构分解为可以彼此独立运行的单个部分。

第二个变化是考虑故障管理,通过风险操作的委派来保护应用程序的重要部分免于级联故障。

由于Actor与其他Actor同时运行,因此重要的是不要在Actor之间共享可变状态-Actor应该仅通过消息进行交互。

但是,在Actor内部运行的代码(即行为)是正常的,需要我打电话的方法。
Jafar Husain:如果您已经知道如何使用功能组合来转换集合,则无需更改编程方式。 值得指出的是,Observable实际上是延续单声道的稍微改写版本,副作用会延迟到您订阅为止。 但是实际上,开发人员实际上并不需要了解Monad才能使用RX。 在Netflix,我们培训开发人员使用这种技术,而无需提及“ M”字样。

InfoQ:您的编程语言或平台是否会带来任何好处,或者它使事情变得复杂或完全不可能? 您想分享一些特殊的实施挑战吗?

Viktor Klang: Akka Actors可以轻松地创建可以根据需要进行扩展和收缩的应用程序-无论大小,它都可以工作,例如,我们最近在Google Compute Engine上进行了一个实验,在该计算机上我们运行了2500个Akka节点一个集群。

Scala是实现Akka的语言,它对不可变,高效的数据结构提供了很好的支持,并且使使用“案例类”创建不可变消息类型非常简单。

说到挑战,我想到了两个:创建大多数并发协调的无锁版本; 以及Akka Cluster的研究和实施,这本身就是一个漫长有趣的故事。
Jafar Husain:显然,如果您的编程语言带有闭包,则以函数式风格编写会更容易。 这也许是将Rx移植到Java的最大障碍。 负责Netflix受欢迎的开源Java Rx端口的本·克里斯滕森(Ben Christensen)已经为Scala,Clojure和Groovy等多种语言创建了适配器,以使RX在JVM上更易于使用。 随着Java 8的发布,在Java中使用Rx也将变得更加容易,该版本首次将闭包引入了该语言。
蒂莫西·巴尔德里奇(Timothy Baldridge): Clojure语言支持一种非常高级的宏系统,该宏系统允许程序员根据需要扩展该语言。 这使我们无需接触Clojure编译器就可以编写整个core.async库。 这样做的另一个好处是将库移植到ClojureScript只需几个小时,而不是几天或几周。

我认为,这表明Clojure和core.async的真正力量。 能够在JVM上为Clojure编写异步代码,然后使其在浏览器中的ClojureScript上“正常工作”是非常强大的。

关于小组成员

Jafar Husain从事软件开发工作已有18年。 他为GE,Microsoft和Netflix等公司开发了软件。 他目前是Java标准委员会TC39的成员。 他专门研究使用功能性React式编程来构建Web服务器和客户端,并且是为所有Netflix设备供电的“ Falkor”协议的架构师。 他是一位受好评的演讲者,他谈到了QCon,YOW!的React式编程,并接受了第9频道有关此主题的采访。 他还编写了交互式培训软件,以帮助开发人员学习功能React式编程。
Timothy Baldridge(@timbaldridge)是Cognitect Inc.的开发人员。他来自美国丹佛科罗拉多州的山区。 Timothy是一名多语言程序员,在Clojure,C#,Python和Erlang方面经验丰富。 最近,他深入参与Clojure的Core.Async库的开发,他在其中设计,实现和维护了状态机代码的重写。
宏称为“ go”。
Viktor Klang (@viktorklang)是Typesafe的首席架构师和Akka项目的前技术主管。他对JVM有着悠久的背景,并且目前对并发,异步,分布式和弹性编程充满热情。

翻译自: https://www.infoq.com/articles/reactive-vp/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

react编程式路由

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值