[IMP] base, mail: cache user.has_group() + ir.ui.menu.load*()
authorOlivier Dony <odo@openerp.com>
Thu, 17 Jul 2014 15:18:14 +0000 (17:18 +0200)
committerOlivier Dony <odo@openerp.com>
Thu, 17 Jul 2014 16:46:10 +0000 (18:46 +0200)
Loading the menus is the most expensive
operation for an average page load, and
the result does not change often.
The menu filtering already uses a separate
cache based on groups, but the rest of the
loading includes reading actions and
translating menu names, which is also
expensive.

Added a cache keyed on user + user
lang, plus relevant cache invalidation
when any of the following are touched:
access rights, user data including
groups and language, menus or mail.group
subscriptions.

The menu filtering cache is still
useful in parallel has it is invalidated
under different conditions.

User.has_group() is cheap but still
called very often, so it is an easy
win as well, and also frequently
used when rendering page templates.

addons/mail/mail_thread.py
openerp/addons/base/ir/ir_ui_menu.py
openerp/addons/base/res/res_users.py

index e4ab8fe..c50e6d0 100644 (file)
@@ -1660,7 +1660,10 @@ class mail_thread(osv.AbstractModel):
         if user_ids is None:
             user_ids = [uid]
         partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
-        return self.message_subscribe(cr, uid, ids, partner_ids, subtype_ids=subtype_ids, context=context)
+        result = self.message_subscribe(cr, uid, ids, partner_ids, subtype_ids=subtype_ids, context=context)
+        if partner_ids and result:
+            self.pool['ir.ui.menu'].clear_cache()
+        return result
 
     def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None):
         """ Add partners to the records followers. """
@@ -1720,7 +1723,10 @@ class mail_thread(osv.AbstractModel):
         if user_ids is None:
             user_ids = [uid]
         partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
-        return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
+        result = self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
+        if partner_ids and result:
+            self.pool['ir.ui.menu'].clear_cache()
+        return result
 
     def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
         """ Remove partners from the records followers. """
index d55451d..45f1b81 100644 (file)
@@ -53,6 +53,8 @@ class ir_ui_menu(osv.osv):
                 # but since we do not use it, set it by ourself.
                 self.pool._any_cache_cleared = True
             self._menu_cache.clear()
+        self.load_menus_root._orig.clear_cache(self)
+        self.load_menus._orig.clear_cache(self)
 
     @api.multi
     @api.returns('self')
@@ -352,6 +354,8 @@ class ir_ui_menu(osv.osv):
         menu_domain = [('parent_id', '=', False)]
         return self.search(cr, uid, menu_domain, context=context)
 
+    @api.cr_uid_context
+    @tools.ormcache_context(accepted_keys=('lang',))
     def load_menus_root(self, cr, uid, context=None):
         fields = ['name', 'sequence', 'parent_id', 'action']
         menu_root_ids = self.get_user_roots(cr, uid, context=context)
@@ -364,6 +368,9 @@ class ir_ui_menu(osv.osv):
             'all_menu_ids': menu_root_ids,
         }
 
+
+    @api.cr_uid_context
+    @tools.ormcache_context(accepted_keys=('lang',))
     def load_menus(self, cr, uid, context=None):
         """ Loads all menu items (all applications and their sub-menus).
 
index f81ac0c..5f2ad71 100644 (file)
@@ -126,6 +126,7 @@ class res_groups(osv.osv):
                         _('The name of the group can not start with "-"'))
         res = super(res_groups, self).write(cr, uid, ids, vals, context=context)
         self.pool['ir.model.access'].call_cache_clearing_methods(cr)
+        self.pool['res.users'].has_group.clear_cache(self.pool['res.users'])
         return res
 
 class res_users(osv.osv):
@@ -329,6 +330,7 @@ class res_users(osv.osv):
                 if id in self._uid_cache[db]:
                     del self._uid_cache[db][id]
         self.context_get.clear_cache(self)
+        self.has_group.clear_cache(self)
         return res
 
     def unlink(self, cr, uid, ids, context=None):
@@ -511,6 +513,7 @@ class res_users(osv.osv):
             'target': 'new',
         }
 
+    @tools.ormcache(skiparg=2)
     def has_group(self, cr, uid, group_ext_id):
         """Checks whether user belongs to given group.