Problem
I needed to run multiple UDP servers on different ports that exchange data with a Django core, so I defined a Django command which calls a method (start_udp_core
) that runs each UDP server in a separate process. I used socketserver.UDPServer
and stored the needed data for the socket using a Django model called ServerData
. The Django version is 4.0.5
So I came up with this code:
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()
After running the command using manage.py
, AppRegistryNotReady: Apps aren't loaded yet
is being raised:
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
Now, there are duplicate lines because there are two ServerData
's in db and as you see server data list is fetched and logged successfully. Any ideas on "why this happens?" question? (I tested the multiprocessing code before binding it to Django and there was no problem.)
Fix
I moved create_and_start_server
function to another file and ran the command again and it worked!!
See the log below:
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)
So now I wonder how this is possible? I will appreciate any helpful explanation.
Update
This problem is persistent on macOS with the same traceback even after the fix.