Skip to content

Commit a44e422

Browse files
committed
Fix DatabaseSyncToAsync
- copy/use connections from the main thread, which are in an atomic block (used in tests) - do not close connections in atomic blocks Ref: #1091 (comment)
1 parent 9b1e084 commit a44e422

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

channels/db.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,48 @@
1-
from django.db import close_old_connections
1+
from concurrent.futures import ThreadPoolExecutor
2+
3+
from django.db import connections
24

35
from asgiref.sync import SyncToAsync
46

7+
main_thread_connections = {name: connections[name] for name in connections}
8+
9+
10+
def _inherit_main_thread_connections():
11+
"""Copy/use DB connections in atomic block from main thread.
12+
13+
This is required for tests using Django's TestCase.
14+
"""
15+
for name in main_thread_connections:
16+
if main_thread_connections[name].in_atomic_block:
17+
connections[name] = main_thread_connections[name]
18+
connections[name].inc_thread_sharing()
19+
520

621
class DatabaseSyncToAsync(SyncToAsync):
722
"""
8-
SyncToAsync version that cleans up old database connections when it exits.
23+
SyncToAsync version that cleans up old database connections.
924
"""
1025

26+
executor = ThreadPoolExecutor(
27+
# TODO
28+
# max_workers=settings.N_SYNC_DATABASE_CONNECTIONS,
29+
thread_name_prefix='our-database-sync-to-async-',
30+
initializer=_inherit_main_thread_connections,
31+
)
32+
33+
def _close_old_connections(self):
34+
"""Like django.db.close_old_connections, but skipping in_atomic_block."""
35+
for conn in connections.all():
36+
if conn.in_atomic_block:
37+
continue
38+
conn.close_if_unusable_or_obsolete()
39+
1140
def thread_handler(self, loop, *args, **kwargs):
12-
close_old_connections()
41+
self._close_old_connections()
1342
try:
1443
return super().thread_handler(loop, *args, **kwargs)
1544
finally:
16-
close_old_connections()
45+
self._close_old_connections()
1746

1847

1948
# The class is TitleCased, but we want to encourage use as a callable/decorator

0 commit comments

Comments
 (0)