2013-03-18 4 views
7

私は、Djangoで何らかのシャットダウンフックを使って解決したいと思う問題があります。Django Framework - 購読可能なシャットダウンイベントはありますか?

私はまだPython/Django開発の初心者であり、ブラウザで動作するCOMET/Reverse Ajaxスタイルのチャットサイトを開発するプロジェクトを自分で設定しています。ブラウザーはサーバーに継続的にメッセージをポーリングします。サーバーはポーリング要求を受信すると、待機中のメッセージがあるかどうかを確認し、存在しない場合は、すでに獲得されたオブジェクトのスレッドをロックで取得しようとします。これにより、メッセージを受信し、前述のロックが解放されるまで、要求を処理しているスレッドがブロックされます。

私の問題は、サーバをシャットダウンしたときに発生します。この時点で私は開発サーバー(python manage.py runserver)を使用しています。上記のプロセスからブロックされたスレッドがある場合、サーバーはシャットダウンしません。

サーバがシャットダウンを試みたときにコードを実行して、待機中のスレッドを解放できる方法はありますか?

私は以下を見てきましたsimilar questionしかしそれは私を助けませんでした。このようなイベントフックは存在しないとの推測があったが、決定的な答えはなかった。私は高いと低い、グーグルを探検したが、運がなかった。

私はPython 2.7とDjango 1.5を使用しています。任意の助けに感謝

私はシャットダウンイベントの知らない

+0

これがどの程度正確に実装されているかどうか、そしてこれがうまくいくかどうかはわかりませんが、ただそこに置くだけです - すべてのスレッドが「ああ、私はおそらく止めるべきですか? – dmg

+0

@DJV:しかし、そのメッセージを送るのはどうすればわかるのですか? –

+0

dev-serverの 'Ctrl + C'(a.k.a.' KeyboardInterrupt')のための何らかのハンドルです。異なるサーバーの場合、おそらく異なるアプローチが考えられます。私はこれが一般的なアプローチではなく、Django経由ではないことを理解していますが、私は "私はただそこに投げているだけです"と言っています。 – dmg

答えて

4

を提供することができますが、1を作成することができます。

ユーザがCtrl-Cを押すと、SIGINT信号がPythonプロセスに送信されます。 wsgi.pyファイルからシグナルハンドラを設定してSIGINTを捕捉し、プログラムに転送してください。

wsgi.py:あなたもDjangoの信号に信号を送ることができ

... 

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

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。 --noreloadオプションを指定してrunserverを呼び出すか、またはgunicornに切り替えます。

+0

Apache&mod_wsgiでこの動作をどのように取得するか考えていますか? – Ward

2

ステューのGlaで答えることに加え:

# {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) 
:あなたがそうのように、manage.pyのために扱うか、アプリの__init__.pyの初期化を入れて置くことができます
ジャンゴでメインスレッドで信号イベントのハンドラを設定するには

--noreloadなしでサーバーを実行できるようになります。
os.environ.get('RUN_MAIN')のpvevent呼び出し関数を2回確認してください。