We're trying to upgrade from 0.17.3 to master to get the recent PendingMessageStore functionality and seeing a bunch of our tests using channels.tests.Client fail with an InterfaceError: connection already closed
I've tracked the error down to this commit: https://github.com/django/channels/commit/0ed04a9c06707388687bc85637baaf4909f88961
It appears after using the Client.consume method the consumer_finished signal is sent and subsequently django.db.close_old_connections ends up being called which closes the connection.
The next time that connection is used the InterfaceError is thrown
I'm not so clear this is a bug in channels, django or psycopg2 but I figured I would start here.
We've worked around the issue by deregistering the close_old_connections signal receiver in tests but this doesn't feel like an ideal solution.
I've pushed a branch demonstrating this error here: https://github.com/linuxlewis/channels/tree/bug/postgresql-interface-closed
Thank you for your time
Hm, that is weird, I've not been seeing that locally. Hopefully I'll get some time to investigate soon.
We are getting the same. I had to downgrade back to 0.17.3.
I've reproduced the issue across python2/3, ubuntu 14.04/16.04 and postgresql 9.5
Here's a snippet of my current work around for this issue.
# tests/base.py
from channels.signals import consumer_finished
from django.db import close_old_connections
class ChannelsTestMixin(object):
def __init__(self, *args, **kwargs):
super(ChannelsTestMixin, self).__init__(*args, **kwargs)
consumer_finished.disconnect(close_old_connections)
class SomeFailingTestCase(ChannelsTestMixin, TestCase):
pass
I'm seeing the same thing using Python 2.7.10, psycopg2 2.6.2, Django 1.10.5, channels 1.0.2, and postgresql 9.5.4 on OSX. The workaround from @linuxlewis is doing the trick for now.
Hah, Django does this to work around it:
def closing_iterator_wrapper(iterable, close):
try:
for item in iterable:
yield item
finally:
request_finished.disconnect(close_old_connections)
close() # will fire request_finished
request_finished.connect(close_old_connections)
I'll get something similar in now.
OK, that commit should fix it - let me know if things are still a problem.
Most helpful comment
Hah, Django does this to work around it:
I'll get something similar in now.