0

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.

Rooz
  • 21
  • 3

0 Answers0