2011-03-12 60 views
13

我在想,是否有任何语言允许您在不重新加载整个应用程序的情况下即时添加/删除/更新任何类? (假设我可以接受一些不便之处,例如确保目前没有方法运行+额外的努力来“迁移”类数据成员)。哪种编程语言允许即时更新任何类?

Web应用程序,其中您替换1个文件,它用于下一个客户端请求是不是我所需要的(如Perl,PHP)。应用程序必须连续运行,并且它有一些内部状态。

其它要求是

  1. 没有GIL或从利用SMP
  2. 优选地防止类似的问题 - JIT状VM(即,其中性能接近于本机代码)的存在。理想的解决方案是能够在CLang或任何其他基于LLVM的语言中重新加载模块。这将是完美的。

关于已取得的回答:

  • .NET/Java是不适合 - 它们都具有体积太大虚拟机,以及应用程序的显著部分将在Linux上运行。
  • Erlang - 看起来好像是可能的,但这对我的肉眼来说太可怕了,我只是不能冷静对待它,如果是,案例和字符串。此外,我宁愿避免将裸源传输到客户端,编译的字节码会更好。
+5

Appart从那个讨厌的表现的事情,现代Ruby可能会适合您的需求。 – 2011-03-12 17:33:27

+0

我假设你需要一个JIT编译器,而不是一个兼作DVCS的虚拟机? – delnan 2011-03-12 17:50:49

+0

JIT很高兴有,但不是一个严格的要求。 – BarsMonster 2011-03-12 17:51:54

回答

5

Objective-C可能适合该法案。您可以使用here中记录的函数在运行时添加新的类和交换方法实现,并且如果需要额外的实现,则可以在现有类上加载新的NSBundles和其他类或类别。 GNUStep虽然没有实现苹果最新的语言附加功能,但声称实现了这些功能(请参阅[1][2])。

+0

不是。你不能添加实例变量。 Pieter Schoenmakers在他的1999年论文中解释了这一点。请参阅http://gerbil.org/tom/ – 2011-03-22 09:30:17

+0

当然,您可以通过创建子类来添加实例变量。对于现有的类,可以使用'objc_setAssociatedObject'来轻松地“伪造”它。 – Anomie 2011-03-22 11:26:27

3

你试图写什么类型的应用程序?在什么平台上?

GUI与服务器的问题可能会排除Linux与Windows的问题。

下列语言是动态的:

  • Smalltalk的
  • 的Perl
  • 的JavaScript
  • 的VBScript
  • 红宝石

现代JavaScript是目前在军备竞赛是为尽可能快,所以应该很快ny平台。

+1

尽管JS没有类,所以从字面上来说......并不是说基于原型的OOP不是很整齐。 – delnan 2011-03-12 17:51:41

+0

动态只是问题的10%。我不知道用这些语言即时更新类的好方法,以便已创建的实例可以照常运行。平台是Win/Linux。它是分布式的服务器客户端应用程序,没有gui。 – BarsMonster 2011-03-12 17:54:25

+0

我不清楚你写的内容:你希望类的所有实例在类更新时改变,还是只希望新实例改变。不要说“两个”.... :-)另外为什么客户端不能定期重启升级?这不能解决客户端的问题吗? – Ben 2011-03-13 09:04:17

1
+0

这看起来非常非常多汁,唯一的问题是与笨重的JVM轻微的个人不兼容:-) – BarsMonster 2011-03-12 18:13:58

+0

使用第三方实用程序http://www.zeroturnaround.com/jrebel/ – mindas 2011-03-15 16:23:04

15

二郎被设计为支持热代码交换其高的一个可用性功能。

+1

可以做更多热切换/重新部署Erlang确实是这个问题的一个很好的答案。它甚至与原始的askers知识相反,编译成你可以发布的字节码,所以源码不在客户端机器上。 – 2011-03-21 16:40:28

0

Smalltalk可以自然地做到这一点,Common Lisp(CLOS)有一些技巧。

3

Python可以做到这一点。请注意以下几点:

  • multiprocessing模块。
  • GIL特定于CPython它是而不是 Python固有的。
  • GIL不是你问题think它是。它不会影响重要的IO使用,并且doesn't apply to C code或C库(如果wrapped correctly)。如果你正在做计算密集型的任何事情,无论如何都应该用C语言(无论如何都是这些部分)。
+0

我真的需要线程,我需要它们之间共享的所有数据,而且对于进程来说更难。另外,不能安全地启动1000个进程。由于IronPyton&JPython不适用于我,因此我检查了PyPy并发现它也遭受GIL的攻击,以便不破坏与现有C库的兼容性。 – BarsMonster 2011-03-17 10:25:23

+0

@BarsMonster:如果不知道你的问题是什么,我会补充一点,你的观点只代表CPU密集型,算法相关的数据共享,比如重型并行计算,或者你在Windows上。如果是这种情况,您应该考虑C,并将计算包装在模块中以供更高级别的语言使用。所有其他情况下只求求基于进程的并行化:http://stackoverflow.com/questions/3609469/what-are-the-thread-limitations-when-working-on-linux-compared-to-processes-for- n/3705919#3705919 – 2011-03-17 21:51:29

+0

一个人无法安全地启动1000个进程?新闻给任何人谁程序Erlang .... – 2011-03-21 12:12:57

2

看看Scheme吧。您可以使用非常简单的扩展名在Scheme中执行面向对象的编程,例如Berkeley extensions。只需扩展代码以允许替换方法(应该很容易),然而,无论您想要如何都可以热插拔它们 - 语法仍然保持简单,因为,它是Scheme。 :)

眼下,对于classlooks类似代码:

(define-class (person name) 
    (method (greet) (print `Hello!)) 
    ...) 

其中person是一个lambda。例如,将define-class宏更改为person应该很容易,因此您可以动态添加或删除该列表。

3

我最近做了一些零停机服务迁移的研究。我的解决方案不是一种与语言相关的解决方案。这里有个想法,我们可以转储当前服务的状态,创建另一个进程,将连接状态描述转移到新进程,最终终止旧进程。如下面的图中示出:

enter image description here

具有良好定义抽象服务描述格式和迁移协议,则可以从一个过程到另一个,这意味着,可以用C的服务器迁移的任何种类的服务++ ,并将服务迁移到用Python编写的新进程中,而不会发生任何断开连接。诅咒,你可以将你的服务从旧版本迁移到新版本。添加/删除/更新类不会成为问题。欲了解更多的细节,你可以参考我的文章

Zero-downtime service migration

这种技术的难度,你必须转储正在运行的服务的所有状态并加载它们对另一个进程。对于大多数图书馆你可以发现,很难获得这些类的内部状态,这意味着你可能需要对它们进行一些破解或者编写自己的图书馆。为复杂的服务转移服务状态将是一场噩梦,但对于简单的服务来说,这并不是什么大问题。

0

您可以在列表中查看http://en.wikipedia.org/wiki/List_of_programming_languages_by_category#Reflective_languages。我在这里没有提到的一个是Lua,与其他动态语言相比,Lua声名狼借。

另一个策略可能是看看学术研究。一个可能的起点是http://scholar.google.com/scholar?q=ksplice,它是关于修补正在运行的linux内核的。

我不确定你要找什么样的自动化程度。很明显,无缝地用A代替一个运行的程序A实例的一般情况很难,即使有一些保证允许在A中允许改变。

根据程序是如何的需要进行更新可以分组和孤立的作品,你可以把它们放在一个共享库,并(重新)加载在运行时共享库​​(例如使用了dlopen的家庭的功能,如果你在Unix上)。

1

取决于您的项目的具体情况 - Javascript可能是通过Node.js(nodejs.com)的答案,它允许您使用由V8引擎解释的JavaScript编写基于事件的服务器。

与传统网络服务器相比,在一次有很多连接的情况下,特别是在服务器有很多空闲的情况下,这种方法可以非常有效。这是由于Javascript的基于事件的特性导致空闲成本非常低的原因。

有如何使用Node.js用于热交换代码的几种方法 - 这应该让你开始:Node.Js in Erlang style?https://github.com/kriszyp/nodules

+0

由于无共享构造node.js,SMP *可能成为问题。 – 2011-03-21 16:41:52

3

我们这样做是对宝石的免费版本上运行的海边Smalltalk的web应用。宝石在过去20年左右一直在这样做,所以他们拥有你需要的一切。某些高可用性功能不是免费的。

开源smalltalks没有广泛的类版本/迁移宝石有。简单的“加载新版本并迁移所有实例”适用于所有smalltalks。

0

你应该使用PHP对于这一点,我也有一台Linux服务器,这是非常好的有权更改文件,就像我有这个PHP代码打开一个文本框,可编辑的站点文件,

<?php 
$fn = "test.txt"; //the path to any file 

if (isset($_POST['content'])) 
{ 
    $content = stripslashes($_POST['content']); 
    $fp = fopen($fn,"w") or die ("Error opening file in write mode!"); 
    fputs($fp,$content); 
    fclose($fp) or die ("Error closing file!"); 
} 
?> 
<h4>You are editing <?php echo $fn ?> </h4> 
<form action="<?php echo $_SERVER["PHP_SELF"] ?>" method="post"> 
    <textarea rows="25" cols="40" name="content"><?php readfile($fn); ?></textarea> 
    <br/> 
    <input type="submit" value="Save"> 
</form> 
0

Objective-C允许你热切换代码,并且有一个允许这样做的插件。我回答了类似的问题Objective-C here