简体   繁体   English

是否可以同时运行不同的Erlang OTP版本?

[英]Is it possible to run different Erlang OTP version at the same time?

I am trying to add Apple's voip push notification into our app. 我正在尝试将Apple的voip推送通知添加到我们的应用程序中。 Our backend provider is written by Erlang's Ejabberd server with apns4erl server 1.0.4. 我们的后端提供程序由Erlang的Ejabberd服务器和apns4erl服务器1.0.4编写。

Currently, the apns4erl 2 has the capability to send voip push notification. 目前,apns4erl 2具有发送voip推送通知的能力。 But it require OTP 19+ to compile and our system is running on OTP 17.3. 但它需要OTP 19+进行编译,我们的系统在OTP 17.3上运行。

So may I know is that possible to run these two OTP at the same time? 所以我可以知道是否可以同时运行这两个OTP? I can't upgrade OTP to 19+. 我无法将OTP升级到19+。 And new library require 19+. 新图书馆需要19岁以上。

Are there good way to make this requirement possible or I need to porting the new library into our old one? 是否有可能使这个要求成为可能,或者我需要将新库移植到旧库中?

Thanks, 谢谢,

Eric 埃里克

Keep in mind while reading this that you should really find a way to update your existing service to keep up to date with newer runtimes. 请注意,在读这是你应该找到一种方法来更新现有服务,以跟上较新的运行时间。 I've dealt with being stuck on a legacy runtime only because someone thought they needed to fork a particular module somewhere in a way that made it impossible to upgrade -- and that was just a nightmare. 我只是因为有人认为他们需要以一种无法升级的方式将某个特定模块分叉 - 而这只是一场噩梦。

TL;DR: (But you should read it anyway) TL; DR :(但无论如何你应该读它)

Yes, I just confirmed that you can connect an R17 and an R20 node via disterl and send messages: 是的,我刚刚确认您可以通过disterl连接R17和R20节点并发送消息:

R17 node: R17节点:

ceverett@changa:/opt/erlang/R17.5/bin$ ./erl -name bar -cookie walnut
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V6.4  (abort with ^G)
(bar@changa.shinden.tsuriai.jp)1> P = spawn(fun Wait() -> receive {From, Message} -> From ! {received, Message}, Wait() end end).
<0.44.0>
(bar@changa.shinden.tsuriai.jp)2> global:register_name(waiter, P).
yes

R20 node: R20节点:

ceverett@changa:~$ erl -name foo -cookie walnut                                                                                                                                                                                                                              
Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [hipe] [kernel-poll:false]                                                                                                                                         

Eshell V9.0  (abort with ^G)
(foo@changa.shinden.tsuriai.jp)1> net_kernel:connect('bar@changa.shinden.tsuriai.jp').
true
(foo@changa.shinden.tsuriai.jp)2> global:send(waiter, {self(), "blah blah blah"}).
<7489.44.0>
(foo@changa.shinden.tsuriai.jp)3> flush().
Shell got {received,"blah blah blah"}
ok

Note that above the R20 node was started first , so that was the version of EPMD that was running. 需要注意的是,R20节点上方开始第一次 ,所以这是所运行的EPMD的版本。 I have no idea whether that would matter, nor do I know if EPMD has changed between R17 and R20. 我不知道这是否重要,我也不知道EP17D是否在R17和R20之间发生了变化。

This is all undocumented functionality . 这是所有未记录的功能 Read below for a much more future-proof way to do this. 阅读下面的一个更加面向未来的方式做到这一点。

The documented way to connect two nodes of different versions is with the +R runtime flag. 记录的连接不同版本的两个节点的方法是使用+R运行时标志。 I regard this as a wildly unreliable hack (precisely as unreliable as what I demonstrated above) unless you've tested it thoroughly first -- and it may have unintended side effects depending on the versions involved (and no telling what is coming in the future). 我认为这是一个非常不可靠的黑客(正如我上面所说的那样不可靠),除非你先彻底测试过它 - 它可能会产生意想不到的副作用,具体取决于所涉及的版本(并且不知道将来会发生什么) )。 But this is an actual runtime flag and it obviously exists for a reason. 但这是一个实际的运行时标志 ,显然存在是有原因的。 See legoscia's answer for more detail about this. 有关详细信息,请参阅legoscia的答案

Discussion 讨论

Whether or not two versions of Erlang's runtime are compatible over disterl, writing network applications in Erlang is really easy . 无论两个版本的Erlang运行时是否与disterl兼容,在Erlang中编写网络应用程序都非常简单 You can always connect two of any different things over TCP. 您始终可以通过TCP连接两个不同的东西。

The simple solution to this would be to write a network application in Erlang using the current version of Erlang (R20.1 at the moment) that receives Apple voip pushes, and forwards them to your main application. 对此的简单解决方案是使用当前版本的Erlang(目前为R20.1)在Erlang中编写一个网络应用程序,该应用程序接收Apple voip推送,并将它们转发到您的主应用程序。

Write: 写:

  • A single TCP socket handling process inside your R17 system. R17系统内部的单个TCP套接字处理过程。
  • The Apple VOIP push service handler in R20 and a TCP socket connecting process that talks to the R17 TCP socket handler. R20中的Apple VOIP推送服务处理程序和与R17 TCP套接字处理程序通信的TCP套接字连接进程。

Treat the Apple VOIP service within your system as if it exists as a native part of your application . 将系统中的Apple VOIP服务视为应用程序的本机部分 The socket handler in the R17 node is the VOIP service. R17节点中的套接字处理程序 VOIP服务。 Make sure you write its interface functions with that in mind -- later if you can migrate your code to R20 then you won't have to worry with this detail because it will be already abstracted by the internal protocol in Erlang. 确保编写其接口函数时考虑到这一点 - 以后如果您可以将代码迁移到R20,那么您不必担心这个细节,因为它已经被Erlang中的内部协议抽象化了。

As for the push updates themselves, you can create whatever sort of protocol you want. 至于推送更新本身,您可以创建任何类型的协议。

Erlang's external term format has not changed between R17 and R20, so you will be able to send native messages between the two nodes by having the Apple VOIP side socket handler (on the R20 node) do something like: Erlang的外部术语格式在R17和R20之间没有变化,因此您可以通过Apple VOIP侧插槽处理程序(在R20节点上)执行以下操作,在两个节点之间发送本机消息:

notify_node(Socket, VOIP_Data) ->
    Message = term_to_binary({push, VOIP_Data}),
    ok = gen_tcp:send(Socket, Message),
    log(info, "Message sent").

And on the receiving node (the R17 node): 在接收节点(R17节点)上:

loop(Parent, Debug, State = #s{socket = Socket}) ->
    receive
        {tcp, Socket, Bin} ->
            {push, VOIP_Data} = binary_to_term(Bin, [safe]),
            {ok, NewState} = do_stuff(VOIP_Data, State)
            loop(Parent, Debug, NewState);
        %% Your other stuff
        %% OTP system stuff
    end.

You could write the R17 side as a gen_server also, listening for: 您也可以将R17侧写为gen_server,并监听:

handle_info({tcp, Socket, Bin}, State = #s{socket = Socket}) ->
    %% whatever

I just happen to most often see socket handling processes as proc_lib processes instead of gen_servers most of the time. 我碰巧经常看到套接字处理过程作为proc_lib进程而不是gen_servers大多数时间。 But it doesn't matter in most cases. 但在大多数情况下并不重要。

Another approach is to use binaries: 另一种方法是使用二进制文件:

notify_node(Socket, VOIP_Data) ->
    Message = <<"PUSH ", VOIP_Data>>,
    ok = gen_tcp:send(Socket, Message),
    log(info, "Message sent").

And on the receiving node (the R17 node): 在接收节点(R17节点)上:

loop(Parent, Debug, State = #s{socket = Socket}) ->
    receive
        {tcp, Socket, <<"PUSH ", VOIP_Data/binary>>} ->
            {ok, NewState} = do_stuff(VOIP_Data, State)
            loop(Parent, Debug, NewState);
        %% Your other stuff
        %% OTP system stuff
    end.

It really depends on the nature of VOIP_Data . 这实际上取决于VOIP_Data的性质。 If it is a binary itself and the R20 Apple push service should just pass it along without inspecting it, then the raw binary method is easy. 如果它本身就是二进制文件并且R20 Apple推送服务应该只是传递它而不检查它,那么原始二进制方法很容易。 If the R20 side is going to be interpreting the message and converting it to an Erlang message of its own then you'll do much better with the binary_to_term/1 / term_to_binary/2 form. 如果R20侧将要解释的消息,并将其转化为自身的二郎山消息,那么你会做的更好 binary_to_term/1 / term_to_binary/2形式。

zxq9's answer covers everything you need to know for this particular situation. zxq9的答案涵盖了您在这种特殊情况下需要了解的所有内容。 I just want to mention the +R flag: 我只想提一下+R标志:

+R ReleaseNumber
Sets the compatibility mode. 设置兼容模式。

The distribution mechanism is not backward compatible by default. 默认情况下,分发机制不向后兼容。 This flag sets the emulator in compatibility mode with an earlier Erlang/OTP release ReleaseNumber . 此标志将仿真器设置为兼容模式,使用较早的Erlang / OTP版本ReleaseNumber The release number must be in the range <current release>-2..<current release> . 版本号必须在<current release>-2..<current release> This limits the emulator, making it possible for it to communicate with Erlang nodes (as well as C- and Java nodes) running that earlier release. 这限制了模拟器,使其可以与运行早期版本的Erlang节点(以及C节点和Java节点)进行通信。

Note 注意
Ensure that all nodes (Erlang-, C-, and Java nodes) of a distributed Erlang system is of the same Erlang/OTP release, or from two different Erlang/OTP releases X and Y, where all Y nodes have compatibility mode X. 确保分布式Erlang系统的所有节点(Erlang-,C-和Java节点)具有相同的Erlang / OTP版本,或者来自两个不同的Erlang / OTP版本X和Y,其中所有Y节点都具有兼容模式X.

See the erl man page . 请参见erl手册页 Though in practice you will get away with not using this flag, and using wider version spans - it's just not guaranteed to work. 虽然在实践中你会逃避不使用这个标志,并使用更宽版本的跨度 - 它不能保证工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否可以在同一应用程序中同时运行AFNetworking和Alamofire? - Is it possible to run AFNetworking and Alamofire at the same time in the same app? 是否可以同时更改价格以更新我的应用程序的版本 - Is is possible to update a version of my app with price change at the same time 是否可以在iPhoneX上同时运行ARWorldTracking Session和ARFaceTracking Session? - Is it possible to run ARWorldTracking Session and ARFaceTracking Session at the same time on iPhoneX? 是否可以在不同的AVPlayers上同时使用多个AVPlayerLayers? - Is it possible to use multiple AVPlayerLayers at the same time with different AVPlayers? 是否可以同时与CoreData中的两个不同实体进行交互? - is it possible to interact with two different entities in CoreData at the same time? 为NavBar和View设置相同的颜色,但在运行时获得不同的颜色 - Setting same color to NavBar and View but getting different colors on run time Cocos2d:如果两个精灵同时从CCAnimationCache运行相同的CCAnimation,是否会发生运行时错误? - Cocos2d: are there any possible run time errors if two sprites run the same CCAnimation from CCAnimationCache at the same time? 是否可以在xcode中同时在* iphone设备*和* iphone模拟器*中运行应用程序? - Is it possible in xcode to run an application in both the *iphone device* and *iphone simulator* at the same time? 是否可以在同一台机器的不同用户帐户上使用网格运行Appium IOS测试用例 - Is it possible to run Appium IOS test cases using grid on different user accounts of same machine 是否可以在Xcode 10中运行新的IOS版本? - Is it Possible to Run new IOS version in Xcode 10?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM