Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
415 views
in Technique[技术] by (71.8m points)

python - Django Framework - Is there a shutdown event that can be subscribed to?

I have a problem which I am hoping might be solved with some form of shutdown hook in Django.

I am still a beginner with Python/Django development, and to help learn I have set myself a project of developing a COMET/Reverse Ajax style chat site that runs in browser. The browser continuously polls the server for any messages. When the server receives a poll request, it checks to see if there are any messages waiting, and if there are none, it will attempt to acquire a lock on a threading.Lock object which has already been acquired. This causes the thread which is handling the request to block until a message is received and the previously mentioned lock is released.

My problem arises when I shutdown the server. At this point I am using the development server (python manage.py runserver). If there is a thread blocked from the above explained process, then the server does not shutdown.

Is there a way that i can execute code when the server attempts to shutdown so that i can release any waiting threads?

I have looked at the following similar question however it hasn't helped me. There was speculation that such an event hook does not exist, however no definitive answer. I've googled high and low, but haven't had any luck.

I am using Python 2.7 and Django 1.5.

Grateful for any help you can provide

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't know of a shutdown event, but you can create one.

When the user presses Ctrl-C, a SIGINT signal is sent to Python process. Setup a signal handler from your wsgi.py file to catch the SIGINT and forward it to your program.

wsgi.py:

...

import signal
signal.signal(signal.SIGINT, my_signal_handler)

You could even forward the signal to a django signal:

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)

Since signal can only be called from the main thread, this won't work with runserver. Either call runserver with the --noreload option, or switch over to gunicorn.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...