[Django] #34276: LocMemCache not working for multiple threads

22 views
Skip to first unread message

Django

unread,
Jan 20, 2023, 11:29:25 AM1/20/23
to django-...@googlegroups.com
#34276: LocMemCache not working for multiple threads
-----------------------------------------+-----------------------------
Reporter: dhiegomaga | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Keywords: LocMemCache
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+-----------------------------
I have a thread that is initialized on apps.py in a given app in django.

This thread updates the value of a `counter` that is saved in cache, using
`django.core.cache`.

Also I have a view that returns the value of the same cache, in an
endpoint:


{{{
# jobs.py
import threading
import time
from django.core.cache import cache

class MyThread:
def __init__(self) -> None:
self.t = threading.Thread(target=UdpReceiver.receiverLoop,
args=(self,))
self.t.daemon = True
self.count = 1

def receiverLoop(self):
global udpTempVar
while self.running:
time.sleep(3)
self.count += 1
cache.set('count', self.count)

def start(self):
self.running = True
self.t.start()

def stop(self):
self.running = False

# --------------
# apps.py
from django.apps import AppConfig
import os

class MyAppConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "MyApp"

def ready(self) -> None:
from .jobs import MyThread
t= MyThread()

if os.environ.get('RUN_MAIN', None) != 'true':
t.start()
# return super().ready()

# --------------
# views.py
from django.http import JsonResponse
from django.core.cache import cache
# ... other imports

def getCurrentCount(request):
global cache
if request.method == 'GET':
return JsonResponse({
'count': cache.get('count')
})
}}}

I am using
(LocMemCache)[https://docs.djangoproject.com/en/4.1/topics/cache/#local-
memory-caching] in settings.py:


{{{
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
}}}

But when I try to log the result of `cache.get('count')`, it returns
`None`.

The documentation clearly states:

"This cache is **per-process** (see below) and thread-safe."

"Note that each process will have its own private cache instance, which
means no **cross-process caching is possible**. "

I have the impression that they meant the cache is **per-thread** , not **
per-process** . Both my threads are on the same process, so they should
share the same caching, according to the documentation. It also
emphasizes, **no cross-process caching is possible**. It doesn't say **no
cross-threading caching is possible**. But reading other resources I found
online, it seems this is not shared even among threads, so the
documentation is wrong, or there is a bug in this version of Django.

--
Ticket URL: <https://code.djangoproject.com/ticket/34276>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jan 20, 2023, 11:30:14 AM1/20/23
to django-...@googlegroups.com
#34276: LocMemCache not working for multiple threads
-------------------------------+--------------------------------------

Reporter: dhiegomaga | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Resolution:

Keywords: LocMemCache | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by dhiegomaga:

Old description:

New description:

I have a thread that is initialized on apps.py in a given app in django.

This thread updates the value of a `counter` that is saved in cache, using
`django.core.cache`.

Also I have a view that returns the value of the same cache, in an
endpoint:


{{{
# jobs.py
import threading
import time
from django.core.cache import cache

class MyThread:
def __init__(self) -> None:

self.t = threading.Thread(target=MyThread.receiverLoop, args=(self,))

The documentation clearly states:

--

--
Ticket URL: <https://code.djangoproject.com/ticket/34276#comment:1>

Django

unread,
Jan 20, 2023, 11:31:05 AM1/20/23
to django-...@googlegroups.com
#34276: LocMemCache not working for multiple threads
-------------------------------+--------------------------------------
Reporter: dhiegomaga | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Resolution:
Keywords: LocMemCache | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by dhiegomaga:

Old description:

> I have a thread that is initialized on apps.py in a given app in django.
>
> This thread updates the value of a `counter` that is saved in cache,
> using `django.core.cache`.
>
> Also I have a view that returns the value of the same cache, in an
> endpoint:
>

> {{{
> # jobs.py
> import threading
> import time
> from django.core.cache import cache
>
> class MyThread:
> def __init__(self) -> None:

New description:

self.t = threading.Thread(target=MyThread.myLoop, args=(self,))


self.t.daemon = True
self.count = 1

def myLoop(self):

The documentation clearly states:

--

--
Ticket URL: <https://code.djangoproject.com/ticket/34276#comment:2>

Django

unread,
Jan 23, 2023, 5:13:26 AM1/23/23
to django-...@googlegroups.com
#34276: LocMemCache not working for multiple threads
-------------------------------------+-------------------------------------
Reporter: D Bersan | Owner: nobody
Type: Bug | Status: closed
Component: Core (Cache system) | Version: 4.1
Severity: Normal | Resolution: invalid

Keywords: LocMemCache | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => invalid
* component: Uncategorized => Core (Cache system)


Comment:

> The documentation clearly states:
>
> "This cache is **per-process** (see below) and thread-safe."
> "Note that each process will have its own private cache instance, which
means no **cross-process caching is possible**. "
>
> I have the impression that they meant the cache is **per-thread** , not
** per-process** .

The `LocMemCache` cache is safe -- each process and thread gets its own
cache, so there's no chances of conflicts (see
[https://code.djangoproject.com/ticket/7639#comment:3 comment]).

> ... Both my threads are on the same process, so they should share the
same caching, according to the documentation ...

There is nothing in the docs about sharing the same cache instance between
processes or threads.

> It also emphasizes, **no cross-process caching is possible**. It doesn't
say **no cross-threading caching is possible**. But reading other
resources I found online, it seems this is not shared even among threads,
so the documentation is wrong, or there is a bug in this version of
Django.

I would argue that documentation doesn't need to mention everything that
it's not possible. It's also documented:

> ''"To provide thread-safety, a different instance of the cache backend
will be returned for each thread."''

--
Ticket URL: <https://code.djangoproject.com/ticket/34276#comment:3>

Reply all
Reply to author
Forward
0 new messages