Opened 7 years ago

Closed 7 years ago

Last modified 4 years ago

#8311 closed (fixed)

Changeset 8342 makes test suite hang if memcached is not running

Reported by: jcrocholl Owned by: nobody
Component: contrib.sessions Version: master
Severity: Keywords:
Cc: johann@…, trevor Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


Up to changeset [8341] my project works okay. After upgrading to [8342], test hangs at 100% CPU, with the following Traceback after Ctrl+C:

............^CTraceback (most recent call last):
  ... (beginning of doctest stack trace omitted) ...
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/", line 428, in __call__
    return*args, **kwds)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/", line 424, in run
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/", line 281, in __call__
    return*args, **kwds)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/", line 260, in run
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/test/", line 2174, in runTest
    failures, tries =
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/test/", line 1403, in run
    return self.__run(test, compileflags, out)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/test/", line 1267, in __run
    compileflags, 1) in test.globs
  File "<doctest django.contrib.sessions.tests[56]>", line 1, in ?
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/contrib/sessions/backends/", line 233, in flush
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/contrib/sessions/backends/", line 20, in create
    self.session_key = self._get_new_session_key()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/contrib/sessions/backends/", line 137, in _get_new_session_key
    session_key = md5_constructor("%s%s%s%s"
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/", line 188, in randrange
    return int(istart + self._randbelow(width))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/", line 235, in _randbelow
    r = getrandbits(k)

The hanging test seems to be in django.contrib.sessions.tests line 56 or so.

Change History (15)

comment:1 Changed 7 years ago by Alex

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to worksforme
  • Status changed from new to closed

I'm not seeing this on r8350, try svn upping(and clearing out all the .pyc files in django) and if it's still an issue reopen.

comment:2 Changed 7 years ago by mtredinnick

This is a real bug, but, as per this thread on django-users, it seems to be very Mac specific in very specific circumstances. In any case, let's call #8314 the tracking ticket for this one and I'll keep that updated with fixes, etc.

(Triagers, close similar tickets as dupes of #8314.)

comment:3 Changed 7 years ago by jcrocholl

  • Resolution worksforme deleted
  • Status changed from closed to reopened

This problem is different from the crash in the django-users thread, and also different from #8314.

This problem persists after upgrading to [8351]. I have deleted all .pyc files and wiped the installation folder.

This problem is not a Python crash or a stack overflow (but I've experienced both of these too).

Python just keeps running at 100% CPU forever. If I kill it with Ctrl+C, the stack trace always looks like the one I posted originally, except for the exact position of the KeyboardInterrupt. The infinite loop seems to start here:

  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/contrib/sessions/backends/", line 236, in flush
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/django/contrib/sessions/backends/", line 22, in create

I'm working on Mac OS X 10.5.4, with the following packages from MacPorts:

memcached @1.2.5_2 (active)
postgresql83 @8.3.1_0 (active)
postgresql83-server @8.3.1_0 (active)
py-memcached @1.40_0 (active)
py-psycopg @1.1.21_1+postgresql83 (active)
py-psycopg2 @ (active)
python24 @2.4.5_0+darwin_9 (active)

comment:4 follow-up: Changed 7 years ago by mtredinnick

  • milestone set to 1.0 beta
  • Triage Stage changed from Unreviewed to Accepted

@jcrocholl: apologies for not appreciating the difference here.

Would you be able to run the tests with --verbosity=2 and work out which test it is hanging on? That should help narrow down where the problem might be.

Also, is there anything special in the settings file you are using, such as setting a particular cache backend? I can't repeat the issue here, but I might not be exercising the right piece of code (plus I'm not on a Mac). So if you can supply that info, I'll try to do it just with eyeballs.

comment:5 Changed 7 years ago by Alex

  • milestone changed from 1.0 beta to 1.0

comment:6 in reply to: ↑ 4 Changed 7 years ago by jcrocholl

  • Summary changed from Changeset 8342 makes test suite hang to Changeset 8342 makes test suite hang when using memcached

This is the last output of /opt/local/bin/python2.4 test --verbosity=2 before Python hangs at 100% CPU:

Checking absolute path for fixtures...
Trying absolute path for xml fixture 'initial_data'...
No xml fixture 'initial_data' in absolute path.
Trying absolute path for json fixture 'initial_data'...
No json fixture 'initial_data' in absolute path.
Resetting sequences
Installed 120 object(s) from 4 fixture(s)
test_confirm_complete (django.contrib.auth.tests.views.PasswordResetTest) ... ok
test_confirm_different_passwords (django.contrib.auth.tests.views.PasswordResetTest) ... ok
test_confirm_invalid (django.contrib.auth.tests.views.PasswordResetTest) ... ok
test_confirm_invalid_post (django.contrib.auth.tests.views.PasswordResetTest) ... ok
test_confirm_valid (django.contrib.auth.tests.views.PasswordResetTest) ... ok
Email is sent if a valid email address is provided for password reset ... ok
Error is raised if the provided email address isn't currently registered ... ok
Doctest: django.contrib.auth.tests.__test__.BASIC_TESTS ... ok
Doctest: django.contrib.auth.tests.__test__.FORM_TESTS ... ok
Doctest: django.contrib.auth.tests.__test__.TOKEN_GENERATOR_TESTS ... ok
Doctest: django.contrib.sites.tests ... ok
Doctest: django.contrib.contenttypes.tests ... ok
Doctest: django.contrib.sessions.tests ... 

I already pointed out that this was the hanging test, see the bottom of my first post.

The problem goes away if I don't use memcached (by commenting out the following line in

CACHE_BACKEND = 'memcached://'

comment:7 follow-up: Changed 7 years ago by Alex

Does it occur if you use a different cache backend?

comment:8 in reply to: ↑ 7 Changed 7 years ago by jcrocholl

Replying to Alex:

Does it occur if you use a different cache backend?

The problem only occurs with memcached. The test suite works okay with any of the following alternatives:

  • No CACHE_BACKEND specified
  • CACHE_BACKEND = 'locmem:///'
  • CACHE_BACKEND = 'file://cache'

My guess is that memcached fails to delete session keys from the cache.

comment:9 Changed 7 years ago by jcrocholl

  • Cc johann@… added
  • Summary changed from Changeset 8342 makes test suite hang when using memcached to Changeset 8342 makes test suite hang if memcached is not running

Okay, here's the simple solution: The memcached daemon should be running when test is started.

The problem was that memcached was not running on my system. The new session cache code will try to create a new session, but the cache backend will return False when it attempts to save the session to the cache. Then the session code assumes that this session key already exists, and raises CreateError. Then it generates a new session key to try again, and again...

The better solution would be to raise an exception if memcached is selected but unavailable, rather than the current infinite loop. Maybe I should write a patch to limit the number of attempts to 10 or 100? Here's the current implementation:

browser://django/trunk/django/contrib/sessions/backends/ (line 18)

def create(self):
    while True:
        self.session_key = self._get_new_session_key()
        except CreateError:
        self.modified = True

comment:10 Changed 7 years ago by mtredinnick

  • Triage Stage changed from Accepted to Design decision needed

Need to think about what to do with caching when the cache isn't available. Depending on that, it will decide what to do here. Nice to hear it isn't a fundamental problem with the code, however. Thanks for chasing that down to the end. We'll do something about the error handling, but I'm not sure what the right solution is yet.

comment:11 Changed 7 years ago by mtredinnick

(In [8381]) Made a few small tweaks to reduce persistent storage accesses in the session
backend. Refs #8311, although doesn't fix the problem there.

comment:12 Changed 7 years ago by jacob

  • Triage Stage changed from Design decision needed to Accepted

comment:13 Changed 7 years ago by trevor

  • Cc trevor added

comment:14 Changed 7 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [8620]) Fixed #8311 -- Avoid an infinite loop with session key generation when using
the cache backend and memcached goes away (or is not running).

comment:15 Changed 4 years ago by jacob

  • milestone 1.0 deleted

Milestone 1.0 deleted

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