编辑Python文件时自动将更改的代码重新加载到Plone中
项目描述
自动重新加载更改的Python文件 - 将敏捷性带回Plone开发。
collective.autorestart监视Python .py文件的更改,并在您编辑文件时触发重新加载。这样您就不需要在代码编辑运行之间重新启动Plone服务器。collective.autorestart使用plone.reload包来执行实际的代码替换。
文件系统通过inotify接口进行监控,该接口仅适用于Linux。未来的版本将支持其他操作系统,只要有人贡献文件系统监控代码或向作者提供运行操作系统X的新计算机。
特性
递归检测ZCML和Python文件的更改,这些文件为Zope所知
自动在文件更改(保存)时触发重新加载
根据重启是否成功或失败播放音频 - 您可以返回到您的文件,而无需监视终端
依赖项
plone.reload
pyinotify用于监控文件(使用版本0.8.6测试过)
pygame用于音频播放(可选)
threadframe(可选)
pyinotify依赖于Linux内核的inotify功能,因此该应用程序目前仅在Linux上运行。然而,将其移植到其他平台应该是微不足道的。
安装
pyinotify依赖于ctypes包,目前(2009年4月)ctypes包在PyPi中损坏。需要手动安装
wget http://kent.dl.sourceforge.net/sourceforge/ctypes/ctypes-1.0.2.tar.gz tar -xzf ctypes-1.0.2.tar.gz cd ctypes-1.0.2/ python2.4 setup.py build sudo python2.4 setup.py install
Buildout设置
将以下egg添加到您的buildout.cfg中。
- eggs =
collective.autorestart
…
- zcml =
collective.autorstart
重新运行 buildout。
添加声音效果支持
可选地,需要pygame egg 来支持声音。Pygame 依赖于 SDL 开发库
sudo apt-get install libsdl1.2-dev libsdl-mixer1.2-dev
将以下 egg 添加到您的 buildout.cfg 中
eggs = pygame
重新运行 buildout。当 pygame 报告缺少库时,请回答“是”。
用法
使用以下命令在前台以正常方式启动 Plone
bin/instance fg
为了使 collective.autorestart 功能,Zope 必须处于调试模式。collective.autorestart 在生产模式或单元测试模式下不会加载。
collective.autorestart 可能不会立即生效,因为它在后台设置了文件监视器。启动时,您将在终端看到一条消息
collective.autorestart Monitoring 3477 paths 12591 files for changes
编辑任何 Python 文件。当您保存时,应在终端输出
2009-04-15 04:11:37 INFO collective.autorestart Detected file system change:/home/moo/workspace/y-trunk/x/browser/views.py/ 2009-04-15 04:11:37 INFO collective.autorestart Reloading Plone 2009-04-15 04:12:06 INFO collective.autorestart Reloaded done, report:Code reloaded: ...x/browser/views.py
如果您已安装 pygame,则根据代码重新加载是否成功或失败,您将听到声音效果。
日志记录
如果您在使用 collective.autorestart 时遇到问题,可以在 logger.py 中调整日志级别。
将级别设置为 logging.DEBUG,以从产品中获得详细的输出,以查看您的 Python 模块是否正确标记为可重新加载。
IDE 兼容性
至少 Eclipse/PyDev 不喜欢信号处理程序和 pyinotify 在同一应用程序中运行的想法,这会导致 SIGTERM 上的死锁。我已经更新了 idelauncher.py 来反映这些更改。这强制 Zope 在从 IDE 停止时强制关闭 - Data.fs 不会刷新。
线程调试器
从 collective.autorestart 0.2 开始,有一个内部线程死锁调试器。死锁调试器始终启用(即使文件更改监视器未运行)。您需要安装 threadframe egg
eggs = threadframe
线程调试器在 Zope 在 collective.autorestart 运行时拒绝关闭时非常有用(请参阅已知问题)。您也可能发现它对调试其他 Zope 死锁问题也很方便。在这种情况下,您可以使用以下命令将线程转储到您的工文件夹中的 zope-threaddump.txt 文件中
killall -SIGUSR1 python2.4
如果应用程序对 SIGUSR1 不响应,则完全崩溃,唯一的方法是使用 SIGKILL 杀死 Python 解释器来处理这种情况。
已知问题
有时 Zope 进程似乎陷入僵尸状态(类似死亡,但阻止了 HTTP 端口或 Data.fs 访问)。在这种情况下,请手动杀死 Zope
killall -SIGKILL python2.4
它似乎卡在 atexit.py / Py_Finalize() / Thread.join() - 可能是 pyinotify 的错误。这种情况在 Notifier 和 ThreadedNotifier 中都发生了
#0 0xb7f10430 in __kernel_vsyscall () #1 0xb7ecf405 in sem_wait@@GLIBC_2.1 () from /lib/tls/i686/cmov/libpthread.so.0 #2 0x080eadc0 in PyThread_acquire_lock (lock=0x95f5070, waitflag=1) at ../Python/thread_pthread.h:313 #3 0x080eee7c in lock_PyThread_acquire_lock (self=0xb7d31f20, args=0xb7cf502c) at ../Modules/threadmodule.c:63 #4 0x080c01d2 in PyEval_EvalFrame (f=0xfcf23f4) at ../Python/ceval.c:3568 #5 0x080c0d1e in PyEval_EvalCodeEx (co=0xb79f16a0, globals=0xb79d468c, locals=0x0, args=0xfbe0050, argcount=1, kws=0xfbe0054, kwcount=0, defs=0xb79f9258, defcount=1, closure=0x0) at ../Python/ceval.c:2741 #6 0x080bffae in PyEval_EvalFrame (f=0xfbdfef4) at ../Python/ceval.c:3661 #7 0x080c0d1e in PyEval_EvalCodeEx (co=0xb79f6220, globals=0xb79d468c, locals=0x0, args=0xfb5dc30, argcount=1, kws=0xfb5dc34, kwcount=0, defs=0xb79f93b8, defcount=1, closure=0x0) at ../Python/ceval.c:2741 #8 0x080bffae in PyEval_EvalFrame (f=0xfb5dadc) at ../Python/ceval.c:3661 #9 0x080c0d1e in PyEval_EvalCodeEx (co=0xb79f6720, globals=0xb79d468c, locals=0x0, args=0xb79d71f8, argcount=1, kws=0xe433218, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:2741 #10 0x0810c00e in function_call (func=0xb79faa74, arg=0xb79d71ec, kw=0xb7bc2bdc) at ../Objects/funcobject.c:548 #11 0x0805b417 in PyObject_Call (func=0x80, arg=0xb79d71ec, kw=0xb7bc2bdc) at ../Objects/abstract.c:1795 #12 0x080bd8b6 in PyEval_EvalFrame (f=0xfbd092c) at ../Python/ceval.c:3845 #13 0x080c0d1e in PyEval_EvalCodeEx (co=0xb79f6d60, globals=0xb79d40b4, locals=0x0, args=0xb7cf5038, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at ../Python/ceval.c:2741 #14 0x0810bf21 in function_call (func=0xb79fad84, arg=0xb7cf502c, kw=0x0) at ../Objects/funcobject.c:548 #15 0x0805b417 in PyObject_Call (func=0x80, arg=0xb7cf502c, kw=0x0) at ../Objects/abstract.c:1795 #16 0x080b941c in PyEval_CallObjectWithKeywords (func=0xb79fad84, arg=0xb7cf502c, kw=0x0) at ../Python/ceval.c:3435 #17 0x080e5cd9 in Py_Finalize () at ../Python/pythonrun.c:1568 #18 0x08057569 in Py_Main (argc=1, argv=0xbfc11ae4) at ../Modules/main.c:513 #19 0x08056d62 in main (argc=Cannot access memory at address 0x80 ) at ../Modules/python.c:23
新创建的文件不会自动被选中
如果您快速编辑和保存几个文件,一些更改可能会被忽略
ZCML 重新加载似乎使某些 zope.component 工具类(词汇表)无效 - 如果重新加载后出现 ComponentErrors,请进行硬重启
0.1.1 - 0.2
解决了死锁问题(我认为)。pyinotify 0.8.x 默认使用超时无阻塞调用,这阻止了信号正确传播。包装了 Zope 信号处理程序,以便在尝试退出系统之前关闭 pyinotify。
添加了死锁调试器来解决这个问题
线程/重新加载逻辑应该更智能,并且重新加载始终在后台线程中
使用 __init__.py 文件来检测 Python 模块,而不是扫描所有文件夹
添加了信号处理程序和 threaddump 支持
检测是否仅重新加载 Python 模块或所有 ZCML 代码
禁用 collective.autorestart 的生产模式和单元测试
更智能的日志记录器
明确了我们正在针对 pyinotify 0.8.6 进行开发
0.1 - 0.1.1
plone.org 发布
README 语法
0.1
重写了旧的 plonemon 代码库
项目详情
collective.autorestart-0.2.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d030faea6da8b213aa8fb67ad1e92360fdd38f2f36bbe9e200cefe9c3dfa3487 |
|
MD5 | 940a9100b04d852c45be038d63a06634 |
|
BLAKE2b-256 | 848a69e056c41a3203077ab669f228cacabb6f0af36dee60fff8a02940cc0c29 |