Opened 4 months ago
Closed 4 months ago
#35498 closed Uncategorized (duplicate)
Race-condition using Django pylibmc implementation (PyLibMCCache)
Reported by: | Bruno Mayer Paixão | Owned by: | nobody |
---|---|---|---|
Component: | Core (Cache system) | Version: | 3.2 |
Severity: | Normal | Keywords: | cache pylibmc thread-safe |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The Django cache implementation for the pylibmc library (PyLibMCCache) uses the default client, without pooling connections. This library is not thread-safe by default. Although Django stores the cache connections using a thread-safe implementation, a race condition can occur in some scenarios.
I created an example project to reproduce the problem: https://github.com/brunomrpx/django-pylibmc-thread-unsafe-example
The scenario is the following:
- A Django application with uWSGI and threads enabled, using the FetchFromCacheMiddleware and UpdateCacheMiddleware middlewares
- A route that receives a key to be stored in cache, which is requested by multiple users.
- If the key doesn't exist in cache, it is stored using the key as the value.
- If the key exists in cache, the system checks if the key used is the same as the returned value.
- If the key and value are not the same, a key mismatch occurs.
I'm able to receive a cached view as a result of accessing the cache using a user's key. It also results in users accessing keys stored by other users in a production application. At the end of the README in the example repository there are some suggestions to solve the problem, maybe using the ThreadMappedPool (https://github.com/brunomrpx/django-pylibmc-thread-unsafe-example/blob/main/cache/cache.py) would be a good approach.
Thank you for the report! This looks like a duplicate of #33252 and should be fixed.
If you can replicate this issue on Django main, feel free to reopen this ticket 👍