Opened 6 months ago

Closed 5 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.

Change History (1)

comment:1 by Sarah Boyce, 5 months ago

Resolution: duplicate
Status: newclosed

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 👍

Note: See TracTickets for help on using tickets.
Back to Top