2013-03-18 24 views
7

Django'da bir tür kapatma kancası ile çözülebileceğimi umduğum bir sorun var.Django Framework - Abone olunabilecek bir kapatma olayı var mı?

Python/Django geliştirmeye hala yeni başladım ve öğrenmeye yardımcı olmak için kendimi tarayıcıda çalışan bir COMET/Ters Ajax stili sohbet sitesi geliştirme projesi hazırladım. Tarayıcı sürekli olarak herhangi bir mesaj için sunucuyu yoklar. Sunucu bir anket isteği aldığında, bekleyen herhangi bir mesaj olup olmadığını kontrol eder ve eğer hiç değilse, daha önce edinilmiş olan threading.Lock nesnesinde bir kilit elde etmeye çalışır. Bu, bir mesaj alınana ve daha önce bahsedilen kilit serbest bırakılıncaya kadar talebin idare edilmesine neden olan ipliğe neden olur.

Sunucuyu kapattığımda sorunum oluşuyor. Bu noktada geliştirme sunucusunu kullanıyorum (python manage.py runserver). Yukarıda açıklanan işlemden engellenmiş bir iş parçacığı varsa, sunucu kapanmaz.

Sunucu beklemeyi denediğinde, herhangi bir bekleyen ileti dizisini serbest bırakmam için kod çalıştırabilmemin bir yolu var mı?

Aşağıdaki similar question'a baktım, ancak bana yardımcı olmadı. Böyle bir olay çengelinin bulunmadığına dair spekülasyonlar vardı, ancak kesin bir cevap yoktu. Yüksek ve alçak gönüllü oldum, ama hiç şansın olmadı.

Python 2.7 ve Django 1.5 kullanıyorum. Herhangi bir yardım için Minnettar

ben bir kapatma olayı bilmiyorum

+0

Tam olarak bunun nasıl uygulandığından ve bunun işe yarayacağından emin değiliz, ama onu oraya koyacağım - tüm ileti dizilerinin okuyacağı ve "Oh, muhtemelen durmalıyım" şeklinde anlayacağı bir ileti var mı? – dmg

+0

@DJV: Ama bu mesajı nasıl göndermeyi bilirdim? –

+0

Gerçekten emin değilim, dev sunucusu için Ctrl + C' (a.k.a. 'KeyboardInterrupt') için bir tür tutamaç. Farklı sunucular için belki farklı bir yaklaşım düşünülebilir.Bunun genel bir yaklaşım olmadığını ve Django aracılığıyla yapılmadığını, ancak "Ben sadece oraya attığımı" söylediğim gibi anlıyorum. – dmg

cevap

4

sağlayabilir, ancak bir hesap oluşturabilirsiniz.

Kullanıcı Ctrl-C'ye bastığında, Python işlemine bir SIGINT sinyali gönderilir. SIGINT'i yakalamak ve programınıza iletmek için wsgi.py dosyanızdan bir sinyal işleyici kurun.

wsgi.py: Hatta bir Django sinyale iletmek olabilir

... 

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 yana sadece ana iş parçacığı çağrılabilir, bu işe yaramaz runserver. Ya runserver'i --noreload seçeneğiyle arayın ya da tabancaya geçin.

+0

Bu davranışı Apache & mod_wsgi'de nasıl edinebilirim? – Ward

2

eklenmesi Stu Gla'ya tarafından cevap:
django içinde ana iş parçacığı sinyal olayı için işleyicisi ayarlamak için manage.py için taşıma başlatma veya uygulamanızın __init__.py, şöyle koymak koyabilirsiniz:

# {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 olmadan sunucuyu çalıştırmanıza izin verir.
os.environ.get('RUN_MAIN') pvevent çağrı işlevini 2 kez kontrol edin.

İlgili konular