Fix: Make URL cache clearing thread-safe in _django_set_urlconf#1233
Fix: Make URL cache clearing thread-safe in _django_set_urlconf#1233pankaj-bind wants to merge 3 commits into
_django_set_urlconf#1233Conversation
kingbuzzman
left a comment
There was a problem hiding this comment.
If your test is anything to go off of, this does not show a problem currently in the code as it stand. Can you elaborate more?
| pytest.importorskip("xdist") | ||
|
|
||
| django_pytester.makepyfile( | ||
| empty="urlpatterns = []", |
There was a problem hiding this comment.
Not used
| empty="urlpatterns = []", |
| ROOT_URLCONF = "empty" | ||
| """ | ||
| ) | ||
| def test_urls_concurrent(django_pytester: DjangoPytester) -> None: |
There was a problem hiding this comment.
I copied this test over to my main branch, and ran this on py3.13
count=0
while true; do
count=$((count + 1))
if ! pytest tests/test_urls.py -vv > /dev/null 2>&1; then
echo "Test failed on iteration $count"
break
fi
printf "."
doneit has not failed -- keeps going, after 100+ iterations (keep in mind, i only copied the test, not the "fix")
There was a problem hiding this comment.
PS. I also ran this with pytest -n auto (same loop as above) -- no difference, i dont see the race condition
|
pytest-xdist runs workers in separate processes, not threads. So it's unclear what this is intended to fix. |
|
@pankaj-bind I don't want to discourage you, what is the issue you're trying to solve? we can help you with it. |
Problem
When running tests in parallel with
pytest-xdist, the@pytest.mark.urlsfixture can cause a race condition. Multiple test workers may try to modify the globalROOT_URLCONFand clear the URL cache at the same time, leading to unpredictable behavior and intermittent test failures.Solution
This change introduces a
threading.Lock()around the URL configuration and cache-clearing logic in the_django_set_urlconffixture. This ensures that these operations are atomic, preventing multiple threads from interfering with each other and making the URL cache clearing thread-safe.