1

For a game website, I want a player to contest either agains a human or an AI. I am using Django + Channels (Django-4.0.2 asgiref-3.5.0 channels-3.0.4) This is a long way of learning...

Human vs Human: the game take place is the web browser turn by turn. Each time a player connects, it opens a websocket connexion, a move is sent through the socket, processed by the consumer (validated and saved in the database) and sent to the other player. It is managed only with sync programming.

Human vs AI: I try to use the same route as previously. A test branch check if the game is against the computer and process a move instead of receiving it from the other end of the websocket. This AI move can be a blocking operation as it can take from 2 to 5sec. I don't want the receive method of the consumer to wait for the AI to return its move, since I have other operations to do quickly (like update some informations on the client side). Then I thought I could easily take advantage of the allegedly already existing event loop of the channels framework. I could send the AI thinking process to this loop and return the result later to the client through the send method of the consumer. However, when I write:

loop = asyncio.get_event_loop()  
loop.create_task(my_AI_thinking())

Django raises a runtime effort error (the same as described here: https://github.com/django/asgiref/issues/278) telling me there is no running event loop. The solution seemed to be to upgrade asgiref to 3.5.0 which I did but issue not solved.

I think I am a little bit short of background, and some enlightments should help me to understand a little bit more what is the root cause of this fail. My first questions would be:

  1. In the combo django + channels + asgi: which is in charge to run the eventloop?
  2. How to check if indeed one event loop is running whatever the thread?

Maybe your answers wil raise other questions.

FTG
  • 65
  • 1
  • 6

1 Answers1

0

Did you try running your event_loop example on Django 3.2? (and/or with different Python version)? I experienced various problems with Django 4.0 & Python 3.10, so I keep with Django 3.2 and Python3.7/3.8/3.9 for now, maybe your errors are one of these problems?

If you won't be able to get event_loop running, I see two possible alternative solutions:

  1. Open two WS connections: one only for the moves, and the other for all the other stuff, such as updating information on Player's UI, etc.
  2. You can also use multiprocessing to "manually" send calculating AI move to other thread, and then join the two threads again, after receiving the result (the move). To be honest, multiprocessing in Python is quite simple -- it's pretty handy, if you are familiar with the idea of multithreaded applications.

Unfortunately, I have not yet used event loops in channels myself, maybe someone more experienced in that matter will be able to better address your issue.

Mikolaj Buchwald
  • 160
  • 4
  • 14
  • I am working with Django 4.0 and Python 3.8. I'll then downgrade to Django 3.2 and check whether it works. Thanks for the advice. – FTG Feb 28 '22 at 14:02