From 40d8db3a65b07c3cf578dcc7dafe571adc0f4503 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Oct 2011 13:07:56 +0200 Subject: [PATCH] [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 --- addons/web/common/http.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index 314ac8ce717..f496c1564a2 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -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) #----------------------------------------------------------