我有我希望可以用某种形式在Django关闭挂钩的有待解决的问题。
我仍然使用Python / Django开发初学者,并帮助学习我已经给自己设定了发展彗星的项目/反转,在浏览器中运行Ajax风格的聊天网站。 浏览器不断地轮询任何消息服务器。 当服务器接收到的轮询请求时,它检查以查看是否有任何等待消息,并且如果没有,它将尝试获取已经被获取的threading.Lock对象的锁。 这使得正在处理的请求到阻塞,直到接收到消息和前面提到的锁定被解除的线程。
我的问题出现了,当我关闭服务器。 在这一点上我使用的是开发服务器(蟒蛇manage.py runserver命令)。 如果从上面的解释过程阻塞一个线程,则服务器不关机。
有没有办法,我可以执行代码,当服务器尝试关闭,这样我可以释放任何等待的线程的方法吗?
我已经看着下面类似的问题但是它并没有帮助我。 有人猜测,这样的事件钩子并不存在,但是没有明确的答案。 我GOOGLE高有低,但还没有任何运气。
我使用Python 2.7和1.5的Django。
感谢任何帮助,您可以提供
我不知道一个关闭事件,但你可以创建一个。
当用户按下Ctrl-C键,一个SIGINT信号被发送到Python进程。 设置从信号处理程序wsgi.py
文件赶上SIGINT并将其转发给你的程序。
wsgi.py:
...
import signal
signal.signal(signal.SIGINT, my_signal_handler)
你甚至可以转发信号到Django的信号:
my_django_shutdown_signal = django.dispatch.Signal()
def _forward_to_django_shutdown_signal(signal, frame):
my_django_shutdown_signal.send('system')
sys.exit(0) # So runserver does try to exit
signal.signal(signal.SIGINT, _forward_to_django_shutdown_signal)
由于signal
只能从主线程调用,这不会与工作的runserver。 无论是打电话的runserver与--noreload
选项,或者切换到gunicorn。
除了由斯图骨钙回答:
要为在Django的主线程信号的事件处理程序,你可以把处理到manage.py放初始化或您的应用程序的__init__.py,就像这样:
# {project_root}/{your_app}/__init__.py
import os
import signal
import sys
def my_signal_handler(*args):
if os.environ.get('RUN_MAIN') == 'true':
print('stopped'.upper())
sys.exit(0)
signal.signal(signal.SIGINT, my_signal_handler)
它可以让你无需--noreload运行服务器。
检查os.environ.get('RUN_MAIN')
pvevent调用函数的2倍。