Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango and not really reliable sessions
    primarykey
    data
    text
    <p>I have lost one day with struggling with django sessions and it seems that I am not really able to resolve it without coding my own sessions middleware or using some locking. The problem is, sessions are not stored even if the saving is triggered manually. It happens now and then, because of race condition which occurs when multiple simultaneous AJAX requests are sent from the client side. I'm using db backend. The thing is, everything is ok when calling only one start() dajaxice call from the javascript side.</p> <p>So the question, why session is not stored sometimes? Should I lock the segment, where session is being stored? I double checked session_key is still the same. Should not be this resolved in the session middleware module?</p> <p>Settings: SESSION_SAVE_EVERY_REQUEST = True </p> <pre><code>def print_session_keys(request, tmp): session_key = request.session.session_key session = Session.objects.get(session_key=session_key) a = session.get_decoded() print tmp+str(a.keys()) @dajaxice_register def start(request): dajax = Dajax() searchHash = os.urandom(16).encode('hex') data = 1 print_session_keys(request, 'Before: - hash: '+searchHash+' ') request.session.set_expiry(0) request.session[searchHash] = data request.session.modified = True request.session.save() print_session_keys(request, 'After: - hash: '+searchHash+' ') </code></pre> <p><strong>LOG:</strong></p> <p>1 or 2 requestes of 3, are stored fine:</p> <blockquote> <p>Before: - hash: 05f22e8e828a0e6145519e0bb0778357 [u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3', u'usermode', u'_session_expiry']<br> After: - hash: 05f22e8e828a0e6145519e0bb0778357 [u'09cf89e0cbe5fb6a179e1f658d452c6b', u'05f22e8e828a0e6145519e0bb0778357', u'usermode', u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3', u'_session_expiry']</p> </blockquote> <p>BUT:</p> <blockquote> <p>Before: - hash: 071e79041aba16a82a32fe4a77c3b4e0 [u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3', u'usermode', u'_session_expiry']<br> After: - hash: 071e79041aba16a82a32fe4a77c3b4e0 [u'09cf89e0cbe5fb6a179e1f658d452c6b', u'05f22e8e828a0e6145519e0bb0778357', u'usermode', u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3', u'_session_expiry']</p> </blockquote> <p><strong>UPDATE:</strong></p> <p>I ended up with using mutex.acquire() and mutex.release(). It now works, but all exceptions must be caught, otherwise mutex will be not released.</p> <pre><code>mutex.acquire() try: request.session.set_expiry(0) request.session[searchHash] = data request.session.modified = True request.session.save() except SomeException: mutex.release() return dajax.json() mutex.release() </code></pre> <p>So if you are doing multiple requests, all with the same session_key, you need to use some locking. Session data is fetched before django enters the view. That is why, there are co-existing multiple and different instances of the session with the same session_key. So to briefly describe what is happening:</p> <p><strong>1)</strong> Request 1 fetches session data from db<br> <strong>2)</strong> Request 1 hits the view<br> <strong>3)</strong> Request 2 fetches session data from db<br> <strong>4)</strong> Request 2 hits the view<br> <strong>5)</strong> Request 2 saves session[mykey]<br> <strong>6)</strong> Request 1 saves <strong>OLD</strong> session data got from 1) and overwrites session written in 5) <br></p> <p>I Hope this may help somebody.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload