Django AppRegistryNotReady при запуске другого multiprocessing.Process
Проблема
Мне нужно было запустить несколько UDP-серверов на разных портах, которые обмениваются данными с ядром Django, поэтому я определил команду Django, которая вызывает метод (start_udp_core
), запускающий каждый UDP-сервер в отдельном процессе. Я использовал socketserver.UDPServer
и хранил необходимые данные для сокета с помощью модели Django под названием ServerData
. Версия Django - 4.0.5
Итак, я придумал такой код:
from core.models import ServerData
from .data_receiver import UPDRequestHandler
def create_and_start_server(host, server_data):
with UDPServer((host, server_data["port"]), UPDRequestHandler) as server:
try:
logger.info(f"server is listening ... {server.server_address}")
server.serve_forever()
except KeyboardInterrupt:
print("... going off ...")
except Exception as e:
logger.error(str(e))
def start_udp_core():
all_servers = ServerData.objects.values()
logger.info(f"servers data ... {all_servers}")
db.connections.close_all()
default_host = "0.0.0.0"
for server_data in all_servers:
multiprocessing.Process(target=create_and_start_server, args=(default_host, card_data)).start()
После выполнения команды с помощью manage.py
, поднимается вопрос AppRegistryNotReady: Apps aren't loaded yet
:
INFO - start_udp_core - servers data ... - <QuerySet [{'id': 1, 'type_id': 1, 'ip': '192.168.0.50', 'port': 5000}, {'id': 2, 'type_id': 1, 'ip': '192.168.0.51', 'port': 5001}]>
Traceback (most recent call last):
File "<string>", line 1, in <module>
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "c:\...\python\python39\lib\multiprocessing\spawn.py", line 116, in spawn_main
File "c:\...\python\python39\lib\multiprocessing\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "c:\...\python\python39\lib\multiprocessing\spawn.py", line 126, in _main
exitcode = _main(fd, parent_sentinel)
File "c:\...\python\python39\lib\multiprocessing\spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
File "D:\...\project\radio\start_udp_core.py", line 6, in <module>
self = reduction.pickle.load(from_parent)
File "D:\...\project\radio\start_udp_core.py", line 6, in <module>
from core.models import ServerData
File "D:\...\project\core\models.py", line 4, in <module>
from core.models import ServerData
File "D:\...\project\core\models.py", line 4, in <module>
class ServerType(models.Model):
File "D:\...\project\venv\lib\site-packages\django\db\models\base.py", line 128, in __new__
class ServerType(models.Model):
File "D:\...\project\venv\lib\site-packages\django\db\models\base.py", line 128, in __new__
app_config = apps.get_containing_app_config(module)
File "D:\...\project\venv\lib\site-packages\django\apps\registry.py", line 260, in get_containing_app_config
app_config = apps.get_containing_app_config(module)
File "D:\...\project\venv\lib\site-packages\django\apps\registry.py", line 260, in get_containing_app_config
self.check_apps_ready()
File "D:\...\project\venv\lib\site-packages\django\apps\registry.py", line 138, in check_apps_ready
self.check_apps_ready()
File "D:\...\project\venv\lib\site-packages\django\apps\registry.py", line 138, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
Process finished with exit code 0
Теперь, есть дублирующиеся строки, потому что есть два ServerData
в db, и как вы видите, список данных сервера извлекается и регистрируется успешно. Есть идеи по вопросу "почему это происходит?"? (Я протестировал код мультипроцессинга перед привязкой его к Django и никаких проблем не было)
Fix
Я переместил функцию create_and_start_server
в другой файл и запустил команду снова, и она сработала!!!
Смотрите лог ниже:
INFO - start_udp_core - servers data ... - <QuerySet [{'id': 1, 'type_id': 1, 'ip': '192.168.0.50', 'port': 5000}, {'id': 2, 'type_id': 1, 'ip': '192.168.0.51', 'port': 5001}]>
INFO - create_and_start_server - server is listening ... ('0.0.0.0', 5000)
INFO - create_and_start_server - server is listening ... ('0.0.0.0', 5001)
Теперь мне интересно, как это возможно? Я буду благодарен за любое полезное объяснение.