#django
#django
Вопрос:
в моем проекте Django есть приложение, которое переопределяет его AppConfig.ready()
метод. В готовом методе я запускаю отдельный multiprocessing.Process
для обработки потребления из внешней очереди сообщений, это, похоже, вызывает проблемы с автоматической загрузкой при изменениях кода.
def infinite_loop():
while True:
time.sleep(10)
class BrokerConfig(AppConfig):
name = 'backend.broker'
has_started = False
def ready(self):
if not os.environ.get("RUN_MAIN"):
# Avoid running for reloader
return
if BrokerConfig.has_started:
return
BrokerConfig.has_started = True
proc = Process(target=infinite_loop)
proc.start()
По какой-либо причине это приводит к прерыванию автоматической перезагрузки кода. Кажется, что перезагрузчик не может очистить запущенные процессы. Перезагрузчик печатает это, а затем застревает:
.../backend/broker/apps.py changed, reloading.
Способ обойти это — сделать запущенный процесс демоном, но в случае, если такая настройка невозможна, мне все еще интересно, как вы могли бы обойти это.
Я ищу какой-нибудь способ добавить пользовательскую очистку при перезагрузке, но, похоже, я не могу найти способ сделать это. Есть ли какой-либо перехват или сигнал, на который вы можете подписаться, чтобы узнать, была ли запущена перезагрузка?
Ответ №1:
Мне удалось сделать это наоборот, поэтому вместо прослушивания или подключения к какому-либо сигналу Django, чтобы указать «входящая перезагрузка кода», я добавил слушателя в свой запущенный процесс для SIGTERM. Когда происходит перезагрузка, перезагрузка кода приведет к завершению демонических процессов и, таким образом, получению сигнала SIGTERM. Я не нашел способа сделать это с не-демоническими процессами.
Конечное решение
def infinite_loop():
stop = False
def stop():
nonlocal stop
stop = True
signal.signal(signal.SIGTERM, stop)
while True:
if stop:
break
time.sleep(10)
class BrokerConfig(AppConfig):
name = 'backend.broker'
has_started = False
def ready(self):
if not os.environ.get("RUN_MAIN"):
# Avoid running for reloader
return
if BrokerConfig.has_started:
return
BrokerConfig.has_started = True
proc = Process(target=infinite_loop, daemon=True)
proc.start()
Итак, в конце концов, я все-таки выбрал демона, и очистка, которую я хотел, была помещена в область запущенного процесса (как обработчик SIGTERM).