django / django/channels

Intermittent database errors in tests after updating to 4.2

Open
#2,118 13 comments 3 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
6.4k
Forks
826
PR merge metrics
No merged PRs in 30d

Description

In my main project I have two websocket consumers which performs a lot of database-related actions.

With `channels==4.1.0` my unittests with django were proceeding smoothly without any problem (I have already removed any references to `database_sync_to_async` since [this comment](https://github.com/django/channels/issues/1091#issuecomment-2164610295), when I switched to async ORM methods).

After I updated to `channels==4.2.0` it started randomly (see later) throwing database errors after the async tests are executed:
```
django.db.utils.OperationalError: the connection is closed
```

I use a multiprocess testing and I get errors only in the process which is executing consumer-related tests only after those are exeuted, due to how tests are picked up by workers and how the interpreter/host handles threads this error may not occurr.

Hunting down into channels' history I found that in https://github.com/django/channels/pull/2101 it was introduced a work-around to prevent `database_sync_to_async` to close old connections by mocking `close_old_connections` calls in the communicator.

Shortly after, in https://github.com/django/channels/pull/2090 the consumers handle/disconnect got an explicit call to `aclose_old_connections` in their workflow.

My doubt is that there is an execution path in which the mock performed in the communicator is not effective against the db-closure in the consumer, but I need to get more evidences ti get what is going on and how to fix it (currently I had 1 day of errors on my development machine and now I no longer get this error locally but only on github.actions).

Contributor guide

Open the contributing guide

Research direction

Start with the communicator workaround from PR 2101 and the consumer handle/disconnect flow from PR 2090, then reproduce the failure under multiprocess tests. Trace when close_old_connections and aclose_old_connections run around the websocket consumers; done means identifying the failing execution path, preventing the closed connection, and adding a regression test that passes reliably in GitHub Actions.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
backend, databases, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.