如何:不重启服务器就更新模块?

提问

nillfeng <[email protected]>
reply-to        [email protected]
to      python-cn`CPyUG`华蟒用户组 <[email protected]>
date    Thu, Dec 11, 2008 at 15:29
subject [CPyUG:73520] 如何不重启服务器 更新模块

像GAE 那样,更改一个模块后 上传上去,自动就更新了,而不用重启服务. 如何实现?

是否可行 或者 来个请求就查看 文件的最后修改时间 如果与上次不符 就del 掉 重新import.

思路

李富荣 <[email protected]>
reply-to        [email protected]
to      [email protected]
date    Wed, Dec 17, 2008 at 21:39
subject [CPyUG:73952] Re: 如何不重启服务器 更新模块

找到下面的这些东西,觉得有些思路了。

这个问题有2方面需要解决:

问题二还有待进一步研究(研究python的inotify lib)

解决依赖关系的reload

对于问题1,思路如下:

伪码:

class Node:
  children=list_of_Nodes
  file_name=the_relative_source_file
  module=the_module_object
  def reload(self, changed_file_name):
    reloaded=False
    for child_node in self.children:
      reloaded=child_node.reload(changed_file_name) or reloaded
    if reloaded or self.file_name==changed_file_name:
      reload(self.module)
      return True
    else:
      return False

def import_proxy(...):
  module=do_the_real_import()
  make_a_node()
  find_the_correct_point_in_NodeTree()# TODO: how?
  append_the_node_into_the_tree()
  return module

def insert_new_node(new_node, file_name_of_parent, root_node):
   """
   Insert new_node into the tree whoes root is root_node.
   This new_node should be child of the Nodes whoes file name is file_name_of_parent.
   """
   for child in root_node:
       insert_new_node(new_node, file_name_of_parent, child)
   if file_name_of_parent == root_node.file_name:
       root_node.children.append(new_node)

整顿思路

想了各种不同的方案,觉得还是django.utils.autoreload做得不错。 虽然没什么研究成果,但是学到了不少东西。

2008/12/17 Frank.CH <[email protected]>

    这四个方法,是语言层次之上的实现方法;
    我倒觉得这种控制,可以放置语言内部实现上; PVM给定对应的参数实现不同的策略更改;
    或许这样处理更好;

把阶段性的研究结果小结一下:

  1. 在代码层的实现:: django:
    • 原理:django的django/utils/autoreload.py是用os.P_WAIT模式spawn一个子进程,在新进程中,把开发用的server放到一个thread中跑,在主线程中运行一个循环,检测sys.__modules__中被加载的文件的mtime。如果发现文件更改了,就sys.exit(3), server线程自然也就跟着退出。父进程进程检查子进程的exit code, 如果是3,就继续spawn,如此循环下去。

    • 使用方法:

   1 from django.utils import autoreload
   2 autoreload.main(your_server_func, args_for_your_func, kwargs_for_your_func)

---怎样在代码层实现,与应用的环境有关系。

  1. 在代码外面来弄::
    • 可以用inotify监测某个文件夹,如果改变了,就运行服务器的重启命令。
    • 优点是通用性好,而且服务器运行环境也不改变。
    • 缺点是效率不高。
  2. 里应外合::
    • 里:不监视文件夹下的所有文件,而是做一个import代理,在服务器启动的时候运行这个代理。

      • 这样,服务器就能把自己加载了哪些文件告诉外界了。
    • 外:用inotify,检测服务器所用到的文件的改变情况。

    • 这种方法通用性也不错,效率比上面得应该好一些,因为检测的文件不那么多。
  3. 编译器
    • 我不是科班出身,对这么高深的东西,还有待学习。
    • 不过我的想法是,运行程序的时候,真的一条一条去解释。这样就能完全与代码同步了。
    • 缺点应该是运行效率问题,但是也许可以用在开发环境也说不定。
    • 目前我没找到有这种功能的python解释器。我也不知道cpython会不会有这样的选项。

我正在尝试"里应外合"的方法。如果有人有兴趣,欢迎一起讨论!


反馈

MiscItems/2008-12-17 (last edited 2009-12-25 07:19:10 by localhost)

Loading