This is my first post here. I'd like to discuss some ways of fixing the 
issue for Django Channels. <https://github.com/django/channels/issues/962> 
speaking, any test for Channels written with ChannelsLiveServerTestCase 
freezes in MacOS.

As a Mac user, I wanted to find a way to write tests, so I spent nearly 
half a day debugging Channels, and finally got the answer. The thing was 
that Python asyncio library does not behave very well with multiprocessing.

To be specific, ChannelsLiveServerTestCase relies on DaphneProcess, which 
again relies on asyncio. Finally, asyncio is based on Kqueue in BSD-like 
OSes. Unfortunately, Kqueue is not inherited to a child process upon fork(), 
while the file descriptor table does. This causes a problem when the 
DaphneProcess of a child process tries to register event handlers for 
sockets, because the file descriptor is still opened but the Kqueue does 
not exist anymore. At this point, MacOS users see an error: bad file 
descriptor. (I've checked lsof of the file descriptor, and found that it 
points to /dev/null.)

In Unix-like systems, although the above problem does not occur, the file 
descriptor table is shared with its child, so forking while asyncio event 
loop is opened should be avoided if possible. I suggest three ways to get 
around this issue.

1. Close the forked loop and create a new event loop when DaphneProcess
2. Modify multiprocessing-based design to threading-based design. In other 
words, run tests in single process, multi-thread environment.
3. Run tests in single process, single thread environment.

The easiest way is 1, which I already committed in my own fork 
but this looks like a cheating, so I'm not very happy with this solution. 
Nevertheless it passes all tests of Channels and Daphne, and moreover Channels 
tutorial <https://channels.readthedocs.io/en/latest/tutorial/part_4.html> 
works fine with BSD-like OSes such as MacOS. (I've tested on both MacOS and 
Linux.) If you think this is fine, then I will be happy to send a PR.

Which one would be the most desirable design?

You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
For more options, visit https://groups.google.com/d/optout.

Reply via email to