3

Here is the full error: The request's session was deleted before the request completed. The user may have logged out in a concurrent request, for example.

I am using python-memcached with my sessions using my cache. Every few days I get one of these errors. Its thrown by an UpdateError on request.session.save(). It comes from line 60 in sessions/middleware.py. 99% of the time everything works normally. I have seen this error at many different URLs for GET and POST requests. Users report that they are not clicking the logout button. They are also reporting that this happens 5 minutes after logging in, so their sessions are not expiring. I have 0 evictions on my cache for over a month it has been running. If I Google this error, it looks like no one has ever gotten it before.

I think the connections to memcached might be closing for some reason. Its running on localhost. The only other time I saw this error is when I set my cache config to a server that had memcached running but it was not listening on that interface. That would generate this exact exception on every request. So is there some way that memcache is refusing to listen for a second or two or dropping connections?

Here are my settings:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
        'TIMEOUT': 1209600,  # Two weeks
    },
}

SESSION_SAVE_EVERY_REQUEST = True
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_COOKIE_SECURE = CSRF_COOKIE_SECURE = True
SESSION_COOKIE_AGE = 60 * 90  # In 90 minutes

It seems the sure way to cause this error is to run cache.delete with the session key in a shell while the request is running. So something is deleting cache keys. I don't know if its Django or Memcached. Memcached does say STAT evictions 0.

kagronick
  • 2,552
  • 1
  • 24
  • 29
  • 2
    I'm having the same problem - and it seems like there are now exactly three people on the internet that have this problem. ;) Possibly four. – Teekin Jul 05 '17 at 15:37
  • @Teekin I'm not getting it anymore. The things I would check are upgrading memcached, file descriptors for memcached and your web server, and the users each of those is running under. Make memcahed run through a local socket. And add the middleware I pasted below. – kagronick Jul 05 '17 at 19:35
  • I recently noticed that the views that produce this error are mostly called by ajax scripts or that they handle files (e.g. returning images). For my case it's definitely possible that the user logged out in a concurrent request - I just want to prevent this error message all the time. – Daniel K. Jul 14 '17 at 13:08
  • Then just give it a nullhandler in your settings file. – kagronick Jul 16 '17 at 03:21
  • I got this error after i just called set_autocommit(False), commit() etc. I reversed everything. But didn't succeed to solve. weird problem. – Mohammed Shareef C Feb 12 '18 at 10:14

3 Answers3

0

I made this middleware to solve the issue. It seems to have taken care of it. Also check your file descriptor limits.

class SLSessionMiddleware(SessionMiddleware):
    """
    Fixes a bug where sessions sometime fail to be set. Catches the error 10 times and gives up.
    """

    def process_response(self, request, response):

        last_exception = None
        for i in range(10):
            try:
                return super().process_response(request, response)
            except Exception as e:
                request.session.cycle_key()
                time.sleep(1)
                last_exception = e

        raise last_exception
kagronick
  • 2,552
  • 1
  • 24
  • 29
  • 1
    This seems like a very hacky solution. It doesn't surprise me that it doesn't work for Daniel K., because it probably makes a lot of assumptions about the environment. – Teekin Jul 05 '17 at 15:35
  • 1
    @Teekin Oh, yes it is very very hacky. I'm not proud of it at all. Its what I came up with after spending hours on this and getting nowhere. Its a very intermittent issue, and is almost impossible to reproduce, making it very hard to diagnose. – kagronick Jul 06 '17 at 15:23
0

I also experienced this error when I enabled Django's DummyCache to prevent the caching of my views whilst developing (please note I use Redis as my caching backend).

Be sure to disable the DummyCache when trying to access your site's admin.

The Django documentation gives a hint as to why you are seeing the error:

Finally, Django comes with a “dummy” cache that doesn’t actually cache – it just implements the cache interface without doing anything.

I alternative between these two lines in my settings.py file depending on what I am working on.

"BACKEND": 'django.core.cache.backends.dummy.DummyCache' if DEBUG else "django_redis.cache.RedisCache",
"BACKEND": "django_redis.cache.RedisCache",
0

In my case I use SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'.

I see this error with next accesses when I renew data from backup (loaddata or so).

So together with such action it is neccessary to delete corresponding entries in cache: cache.del('django.contrib.sessions.cached_dbo27db603b30jabewi7zkwd78b05zq0vf'). (Or you can delete from redis client or so, of course.)

mirek
  • 1,140
  • 11
  • 10