1

I'm struggling with thread communication in Python. I'm clearly missing something, but I'm new to Python so I don't know very well what I'm doing.

When the server gets a GET request, I want it to get two numbers (x and y coords) from a separate thread, which constantly updates those values and to return those numbers as a response.

I have a simple Django project with the following structure:

enter image description here

it is very basic, made according to tutorial.

When the server starts, I start a thread that looks launches my coordinate generator in a separate thread:

class GpsMockCoordsServiceConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'gps_mock_coords_service'

    def ready(self):
        if os.environ.get('RUN_MAIN', None) != 'true':
            _thread.start_new_thread(CoordsTracker.launch_recognition, ())

CoordsTracker class looks like so:

coords = None
class CoordsTracker:
    #coords = None #tried placin it here, but same effect - it is None when retreived from views.py

    logger = logging.getLogger("CoordsTrackerLogger")

    @staticmethod
    def draw_contours(mask, frame, color):
            ......
        for stuff in stuffs:
                 ......
            CoordsTracker.set_coords((x, y))
                 ......

    @staticmethod
        def launch_recognition():
                ........
           while True:
                    ........
               CoordsTracker.draw_contours(....)
                    ........

   @staticmethod
   def set_coords(new_coords):
       global coords
       CoordsTracker.logger.debug("setting coords " + str(new_coords))
       coords = new_coords # here coords var is OK

   @staticmethod
   def get_coords():
       CoordsTracker.logger.debug(coords) # Here it is OK if I call this method from draw_contours() and is not OK if I call this from views.py file.
       return coords

views.py class has only this method:

def index(request):
    # with CoordsTracker.coords_thread_lock:
    coords = CoordsTracker.get_coords()
    logger.debug("Got coords: " + str(coords)) #if I do a GET request this prints 'Got coords: None'
    return HttpResponse(str(coords))

UPD: after some time debugging with a friend, we found out that it appears that the set_coords() method is called in one process, while get_coords() in another process.

Zmur
  • 322
  • 6
  • 24
  • 1
    This sounds like a multi*process* issue. – user2357112 Oct 22 '21 at 13:06
  • @user2357112supportsMonica yes. But I'm not skilleful enough in Python to understand what's wrong here. – Zmur Oct 22 '21 at 13:09
  • @ljlozano no... So this might help to get data out of that process? Perhaps there is a way to launch that thread from same process I'm working in? – Zmur Oct 22 '21 at 18:11
  • You are starting that from the `ready` method... Django may call that twice (two processes), see [How to avoid AppConfig.ready() method running twice in Django](https://stackoverflow.com/questions/33814615/how-to-avoid-appconfig-ready-method-running-twice-in-django). – Abdul Aziz Barkat Oct 22 '21 at 18:32
  • @AbdulAzizBarkat no, this line: `if os.environ.get('RUN_MAIN', None) != 'true':` ensures that it won't be launched twice. – Zmur Oct 22 '21 at 18:33

1 Answers1

1

I'd recommend implementing some kind of IPC with the middleware you have. But if it's a one-off project, you can just launch the thread (launch_recognition) from wsgi.py somewhere. This will ensure it all runs in the same process.