以 Erlang 风格实现的 Node.js?

7
我对Node.Js和Erlang都是完全的新手。但是,建立一个仿照Erlang行为的Node.js应用程序不是有可能吗?
例如,您可以通过分布式Node.js服务器群传递JSON消息,甚至传递新代码给这些服务器而无需离线,就像Erlang一样。
如果您有一个消息处理程序回调函数,在收到消息时激活该回调函数,则该消息处理程序可以检查该消息是否为代码更新消息,从而用新代码替换自己(当前处理程序)。
因此,应该可以在没有太多麻烦的情况下使Node.Js服务器在进行代码更新时无需停机。

我不太清楚代码更新的情况,但我刚刚发现了一个基于 Erlang OTP supervisor 模型的 Node 库。它的链接是 https://github.com/Pagoda/supervisor。 - David Braun
嗯,4年前。我有点喜欢这个想法。 - Montagist
4个回答

5

不完全正确。

  1. 是的,您可以分发JSON消息
  2. 有关热代码替换的部分稍微复杂,让我解释一下...

好的,首先,您显然需要放置验证等。这应该不是大问题。第一个小问题出现在JSON中,它不允许其中包含任何JS代码/函数,嗯,您可以通过将数据作为字符串发送来解决这个问题。

接下来的问题是,当您想要替换函数/方法时,您需要确保它保持其范围,以便新编译的函数可以访问相同的内容。

借助某些黑暗的eval魔法,这肯定是可能的,但不要指望它像在Erlang中那样自然:

var Script = process.binding('evals').Script;

var hello = 'Hello World';
var test = 42;
function Swappable(initCode) {
    this.execute = function() {}
    this.swap = function(code) {
        this.execute = eval('func = ' + code);
    }
    this.swap(initCode);
}

// Note: Swappable's scope is limited, it won't inherit the local scope in which it was created...
var foo = new Swappable('function(){console.log(hello);return function(){console.log(test)}}')
var cb = foo.execute();
cb();

foo.swap('function(){console.log("Huh, old world?");return function(){console.log(test * test)}}');
var cb = foo.execute();
cb();
console.log(bar.execute());
foo.execute();

输出

Hello World
42
Huh, old world?
1764

这并不保证在所有情况和范围内都能正常工作。另外,语法很糟糕,所以如果你想要热插拔,请使用Erlang。记住:工欲善其事必先利其器。
更新: 在不久的将来,不会有比这更好的东西了,参见: https://github.com/ry/node/issues/issue/46#issue/46/comment/610779

2

1
说实话,那篇文章非常误导人。首先,他没有提到使用的是哪个版本的Node.js。众所周知,2.x版本在将字符串推送到套接字时存在严重问题(正是他所做的),而V8中也存在一些JSON编码/解码的错误。这个字符串问题已经在更新的3.x版本中得到了修复。 - Ivo Wetzel

1

0

我认为使用脚本模块,您可以在无需重新加载服务器的情况下执行JavaScript。

监管进程

一个用于nodejs的小管理脚本。 它运行您的程序,并监视代码更改,因此您可以具有热代码重新加载行为,而不必担心内存泄漏并确保清除所有模块间引用,也不需要一个全新的require系统。

但是当它检测到文件更改时,它会重新加载(非常短暂的离线时间)。


1
使用 Erlang 风格的消息传递,您可以在不重新加载任何内容的情况下进行热交换。您甚至可以在激活新的消息循环之前转换本地状态。 - Roger Johansson
当我谷歌搜索时,我也发现了这个网站=> http://romeda.org/blog/2010/01/hot-code-loading-in-nodejs.html。但是我认为Ryan想把它放进代码库中(但他很忙)。但是目前我不认为它和Erlang一样先进。 - Alfred
我检查了一下,这个方法不会保留模块状态,所以你只能用它来修补静态的、无状态的工具。 - Ivo Wetzel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接