Erlang/o TP 24 highlights

2021-05-12 20:14:00

最后Erlang / OTP 24在这里!发布对我来说大约是10多年来的制作。与现在的传统一样,这个博客帖子将通过帖子到Erlang / OTP,我最兴奋!

Erlang / OTP 24包括来自60多个外部贡献者Totaling1400 +提交,300+ PRS和改变0.5百万(!)代码行的贡献。虽然我是不确定的行号应该计数,因为我们奉承了所有ASMJIT ANDRE生成的WXWidgets支持。如果我们忽略了ASMJIT和WX,则添加了静止的260K行代码,并删除了320k行,大约100k大约我们的版本通常包含。

您可以下载描述更改的README:ERLANG / OTP 24 README.OR,一如既往地查看您感兴趣的应用程序的发行说明。在此处:ERLANG / OTP 24 - ERTS发行说明 - 版本12.0版本。

Erlang / OTP 24最预期的特征必须是JIT编译器。很多关于它的批次:

但是,除了JIT带来的性能增益,我最令人兴奋的是,它是运行诠释的原生代码的好处。我所谈论的是当地代码工具,On Nower可供所有erlang程序员可用,例如与perf的集成。

例如,当构建erlang的小核心的透析器PLT时,这是通过eprof这样的东西的推导方式。

这会增加将PLT从大约1.2秒构建到15秒内的时间。最后,您可以在下面的内容中获取一些,这将指导您拖曳您需要优化的Towhat。也许看看ERL_TYPES:T_HAS_VAR * / 1和检查您是否真的需要拨打13-15万次!

> EPROF:分析(总计)。功能呼叫%[US / Call] ------------------- - ] ERL_TYPES:T_SUP1 / 2 2744805 1.68 752795 [0.27] ERL_TYPES:T_SUBST / 2 2803211 1.92 858180 [0.31] ERL_TYPES:T_LIMIT_K / 2 3783173 2.04 913217 [0.24]地图:Find / 2 4798032 2.14 957223 [0.20] ERL_TYPES:T_HAS_VAR / 1 15943238 5.89 2634428 [0.17] ERL_TYPES:T_HAS_VAR_LIST / 1 13736485 7.51 3360309 [0.24] ----------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - - --------“100.00%44719837 [0.26]

在Erlang / OTP 24中,我们可以获得相同的结果,而无需支付eprof的分析成本。在运行与上述顺笔相同的分析时,运行大约1.3秒钟。

然后我们可以使用Perf报告,热点或SpeedScope等工具来分析结果。

在上面,我们可以看到我们在使用EPROF时大致相同,但有趣的是不完全相同。我会让你的问题留给读者来找出:)

在分析时,在剖析时,我们可以运行以前发生的场景,以便在分析时运行太长。对于那些勇敢的勇气,它可能甚至可以在生产中始终运行貌相!

与perf可以完成的旅程只开始了。在PR-4676中,我们将添加框架指针支持,该支持将在剖析时提供更准确的响尾符,并且最终目标是将映射到Erlangsource码线而不是仅在使用PER PER报告和热点以分析PERF时的功能记录。

Erlang的错误消息倾向于获得很多(有效)的危及态度。已添加两个巨大的新功能,以帮助用户了解某些事情失败。

感谢Richard Carlsson和Hans Bolinder的工作,当您编译商朗代码时,您现在可以获得错误的错误和栏目,并用^--sign一起打印壳体的漏洞,显示误差是何处。例如,如果您编译如下:

$ erlc test.erlt.erl:6:16:只有关联运营商' ='允许在地图建设%6 | #{a => A,B:= B}。%| ^

此行为也扩展到大多数Erlang代码编辑器中,以便使用vscode或Emacs通过Erlang LS或Flycheck您的Alsoget一个较窄的警告/错误指示符,例如使用Erlang LS的Emacs。

涉及错误信息时的其他大变化之一是EEP-54的介绍。在过去的许多BIF(内置函数)中会给出非常密码的错误消息:

在上面的示例中,我们唯一知道的是,一个或多个棘手是无效的,但没有检查文档无法知道哪一个和为什么。这尤其是Forbif的问题,其中参数可能因不同原因而失败,具体取决于参数中不可知的因素。例如,在ETS中:Update_counter呼叫以下:

我们不知道该呼叫是否失败,因为如果在表中未存在的键k,则表格不存在,则表格不存在。

1>元素({a,b,c},1)。 **异常错误:函数元素/ 2中的错误参数称为元素({a,b,c},1)***参数1:不是整数***参数2:不是元组2> ETS:new(表,[named_table])。表3> ETS:Update_counter(表,k,1)。 **异常错误:功能ETS中的糟糕参数:UPDATE_COUNTER / 3称为ETS:UPDATE_COUNTER(表,K,1)***参数2:不是表中存在的键

这看起来更好,现在我们可以看到问题是什么!标准记录格式化程序还包括其他信息,如果在生产环境中发生此类错误时,您将重新输入额外的错误信息:

1> proc_lib:spawn(fun() - > ETS:Update_counter(表,k,1)结束)。< 0.94.0> =崩溃报告==== 10-may-2021 :: 11:20:35.367023 == = Crasher:初始呼叫:erl_eval:' -expr / 5-fun-3 - ' / 0 pid:< 0.94.0>注册_Name:[]异常错误:功能ETS中的错误参数:UPDATE_COUNTER / 3称为ETS:UPDATE_COUNTER(表,K,1)***参数1:表标识符不引用现有的ETS表祖先:[< 0.92.0>]

EEP-54不仅适用于来自BIF的错误消息,而且可以使用任何想要提供有关其例外信息的应用程序。例如,我们一直在致力于在PR-4757中提供围绕IO:格式的更好的错误信息。

自Erlang / OTP R14(2010年发布)以来,Erlang编译器和运行时系统都是合作的,以优化Gen_Server使用的代码模式:调用类似功能以避免扫描潜在的邮箱。基本模式如下所示:

呼叫(至msg) - > ref = make_ref(),到! {呼叫,ref,self(),msg},接收{回复,参考,回复} - >回复结束。

编译器可以从这个铭文中,当创建ref时,在包含参考的过程的邮箱中可以有班留言,因此在收到回复时,它会跳过所有这些。

这始终在这样的简单场景中始终繁荣,但只要you adad使场景更加复杂,它往往会打破复选者的分析,并且您将最终扫描整个邮箱。例如,在Erlang / OTP 23下面的代码中不会优化接收。

呼叫(至,msg,异步) - > ref = make_ref(),到! {呼叫,ref,self(),msg},如果异步 - > {好的,ref};不是异步 - >收到{回复,参考,回复} - >回复结束结束。

所有改变都与Erlang / OTP 24变化!许多复杂的方案默认通过优化,并添加了一个新的编译器标志,以告诉众心数子如果完成优化。

$ erlc + recv_opt_info test.erltest.erl:6:警告:优化:用于标记消息队列位置%6 |的参考ref = make_ref(),test.erl:12:警告:优化:所有子句匹配由make_ref / 0创建的参考.erl:6%12 |收到

偶数模式(如Multi_Call)现在优化以不扫描进程的邮箱。

multi_call(polist,msg) - > %%优化:用于标记消息队列位置的引用Ref = make_ref(),%% Info:通过test.erl:18 [to! {呼叫,ref,self(),msg} ||到< - polist],%%信息:通过test.erl:18 %%优化:18 %%的传递引用:所有子句匹配功能参数中的参数2 [接收{回复,参考,回复} - >回复结束|| _< polist]。

这种优化不会触发的很多地方。一旦任何Make_ref / SEND / RECECT在不同的模块中,才能往来一开始就不起作用。但是,Erlang / OTP 24的新改进使得Scenarios的数量较少,现在我们也有工具来检查,看看是否触发了优化!

在拨打另一个erlang进程时,Gen_Server使用的模式:呼叫,Gen_statem:呼叫和其他人通常看起来像这样的东西:

呼叫(到,msg,TMO) - > monref = erlang:监视(过程,to),到! {call,monref,self(),msg},接收{'下降' ,monref,_,_,原因} - > {错误,原因}; {reply,monref,回复} erlang:魔法员(蒙德夫,[刷新]),{好的,回复}在tmo - &gt之后; Erlang:魔法员(Monref,[Flush]),{错误,超时}结束。

除了发生超时时,这通常很好。当Timeouthappens在另一端的过程中没有办法知道回复是所需的NOLONGER,因此在它完成时会发送它。这导致所有问题作为第三方库的用户永远不会知道什么需要在邮箱中存在。

有许多尝试使用Primitivesthat Erlang来解决这个问题,但到底最终只是在他们的Gen_Servers中添加了忽略任何未知消息的Gen_Infoin。

在ERLANG / OTP 24中,EEP-53引入了别名功能来解决这个问题。别名是对可以使用发送消息的过程的临时引用。在大多数方面,它就像一个PID一样,除了别名的寿命没有与进程意图的寿命相关联。因此,当您尝试发送延迟回复的别名时,才能丢弃邮件。

使这种情况发生的代码更改非常小,并且已经在Erlang / OTP的所有标准行为中使用了幕府。上面唯一要在示例代码中更改的内容是新选项必须为Erlang开始:监视器,回复引用现在应该是调用PID的aliasinstead。那就是这样的:

呼叫(到,msg,TMO) - > monalias = erlang:监视器(进程,to,[{alias,emontor}]),到! {呼叫,monalias,monalias,msg},接收{'下降' ,monalias,_,_,原因} - > {错误,原因}; {回复,蒙大亚大亚,回复} Erlang:魔法员(Monalias,[Flush]),{OK,回复} TMO - &gt之后; Erlang:魔法员(Monalias,[Flush]),{错误,超时}结束。

在Erlang / OTP 23中,Erl_Docgen被扩展到能够发出EEP-48 StyleDocumentation。这允许H(列表)Inthe Erlang Shell和Erlang LS等外部工具使用的文档。然而,在Erl_Docgen oTP中使用ERL_DOCGEN TOCREATE文档的exereare很少的应用程序,因此EEP-48样式文件不可用。到现在!

Radek Szymczyszyn已增加对EEP-48的支持,该eDOC是从Erlang / OTP 24中的意思,您可以查看列表的文档:Foldl / 3和Recon:Info / 1。

$ rebar3作为文档shellerlang / otp 24 [ofts-12.0] [source] [giit] eshell v11.2.1(中止^ g)1> h(侦察,信息,1)。 -spec信息(pidterm) - > [{info_type(),[{info_key(),value}]},......]当pidterm :: pid_term()时。允许类似于erlang:process_info / 1,但排除邮箱等字段,往往在生产系统中调用时趋于增长并保持不安全。还包括多于通常给出的字段(监视,监视器,监视器,监视器等),并根据包含的信息的类型将字段以更可读的格式分隔。

有关如何在EDOC用户指南中的项目Seethe Doc Chunks部分中启用它的详细信息。

Gen_TCP模块已支持,可选地使用新的SocketNIF API而不是先前的INET驱动程序。新接口可以通过设置如下所示的应用程序配置参数来配置新的接口:-kernel Inet_Backend套接字,或者在这样的匹配基础上:Gen_TCP:Connect(LocalHost,8080,[{Inet_Backend,Socket}]) 。

如果您这样做,您会注意到Gen_TCP返回的套接字不再是一个端口,而不是包含一个PID和BERFERED的元组

此数据结构始终是不透明的,因此不应被检查,而是仅用作其他Gen_TCP和Inetfunction的参数。

然后,您可以使用INET:I / 0获取系统中所有打开套接字的列表:

2&gt; INET:I()。端口模块RECV发送所有者本地地址外地地址状态类型ESOCK [19] GEN_TCP_SOCKET 0 0 < 0。 98。 0&gt; localhost:44082 localhost:http - alt cd:sd流

Gen_TCP API应完全向后兼容Goldimplementation,因此如果您可以,请测试并报告您对我们来说的任何错误。

你为什么要测试这个?因为在我们的一些基准中,我们得到了吞吐量的4倍,而旧的实现。在别人中,没有差异甚至吞吐量损失。所以,一如既往,你需要积水并检查自己!

在创建管理ConnectionSUCH作为SSL或SSH的应用程序的管理程序的层次结构时,有时需要从内部终止主管层次结构。一些事件发生在套接字上,即触发与连接相关联的进程的正常关闭。

它要求孩子知道需要终止的孩子的ID和主管的PID交谈。当监督员刚刚获得过程时,这很简单,但当有过主管的弱者时,这变得越来越难以弄清楚。

调用主管:terminate_child / 2是同步操作。这意味着如果您在孩子中进行呼叫,您可能会在僵局中最终成为一个僵局,因为TopsuperVisor希望在孩子在Callto终止上终止孩子时终止孩子。

为了解决这个问题,EEP-56已经增加了一种机制,其中一个孩子可以像这样一个人那样偏重,如果这样的孩子终止,它可以触发它的主管是一部分的主导者。

这样一个子程进程可以触发来自inwithin的监督层次结构的关闭,如果在终止期间,没有孩子必须了解风险锁定自身的主控层。

使用Erlang / OTP 24来支持Edwards-Curve数字签名算法(EDDSA)。连接或充当TLS 1.3Client / Server时,可以使用EDDSA。

EDDSA是一种椭圆曲线签名算法(ECDSA),可用于安全通信。 ECDSA的安全性依赖于强大的加密安全随机数,这可能导致随机数量的问题是错误的,因为在ecdsa的几乎没有足够的情况下,如此,据我们所知,所以据我们所知

eddsa并不依赖于强大的随机数来获得安全。这意味着您使用EDDSA时,即使您的OrceNumber发生器不是,通信也是安全的。

尽管安全性增加,但德德萨被声称比其他ElepicCurve签名算法更快。如果您已openssl 1.1.1或更高版本,那么随着Overlang / OTP 24,您将访问此算法!