#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:
>     self.t = threading.Thread(target=MyThread.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.

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.myLoop, args=(self,))
     self.t.daemon = True
     self.count = 1

   def myLoop(self):
     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#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070185d004eb5e-9d2c8884-7054-4cb1-b12e-b9206f1f13a5-000000%40eu-central-1.amazonses.com.

Reply via email to