[FIX] concurrent requests overwriting each other's literal contexts and domains dicts ~/projects/tiny/web/current

also prune empty/useless openerp sessions from the http sessions
before saving the http session, in order not to have *kilobytes* of
crud lying around the magnetic tape

bzr revid: xmo@openerp.com-20111017110756-sqociibor79i6svz
This commit is contained in:
Xavier Morel
2011-10-17 13:07:56 +02:00
parent 6591e6448e
commit 40d8db3a65
+29
View File
@@ -296,6 +296,35 @@ def session_context(request, storage_path, session_cookie='sessionid'):
try:
yield request.session
finally:
# Remove all OpenERPSession instances with no uid, they're generated
# either by login process or by HTTP requests without an OpenERP
# session id, and are generally noise
for key, value in request.session.items():
if isinstance(value, session.OpenERPSession) and not value._uid:
del request.session[key]
# FIXME: remove this when non-literals disappear
if sid:
# Re-load sessions from storage and merge non-literal
# contexts and domains (they're indexed by hash of the
# content so conflicts should auto-resolve), otherwise if
# two requests alter those concurrently the last to finish
# will overwrite the previous one, leading to loss of data
# (a non-literal is lost even though it was sent to the
# client and client errors)
#
# note that domains_store and contexts_store are append-only (we
# only ever add items to them), so we can just update one with the
# other to get the right result, if we want to merge the
# ``context`` dict we'll need something smarter
in_store = session_store.get(sid)
for k, v in request.session.iteritems():
stored = in_store.get(k)
if stored and isinstance(v, session.OpenERPSession)\
and v != stored:
v.contexts_store.update(stored.contexts_store)
v.domains_store.update(stored.domains_store)
session_store.save(request.session)
#----------------------------------------------------------