From bad65600922cf8fae198a740ef28e7f739f07530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com> Date: Sat, 25 Nov 2006 10:49:41 +0000 Subject: [PATCH] Patch DCWorkflow again to use ERP5 Cache Tool to control worklists caching. Each workflow can use a different cache factory (default cache is used if nothing defined). git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@11483 20353a03-c40f-0410-a6d1-a30d3c3de9de --- .../ERP5Type/dtml/workflow_properties.dtml | 16 ++++++++ product/ERP5Type/patches/DCWorkflow.py | 34 +++++++++++------ product/ERP5Type/tests/testCacheTool.py | 38 +++++++++++++++++++ 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/product/ERP5Type/dtml/workflow_properties.dtml b/product/ERP5Type/dtml/workflow_properties.dtml index acb96e6318..d9e6abaa6e 100644 --- a/product/ERP5Type/dtml/workflow_properties.dtml +++ b/product/ERP5Type/dtml/workflow_properties.dtml @@ -19,6 +19,22 @@ <td><textarea name="description" rows="5" cols="80">&dtml-description;</textarea></td> </tr> +<dtml-if "context.portal_caches"> +<tr> +<th align="left">Worklists Cache</th> +<td> + <select name="cache_factory_id" > + <option value=""/> + <dtml-in "context.portal_caches.objectItems()"> + <option value="&dtml-sequence-key;" + <dtml-if "_['sequence-key']==getattr(context, 'cache_factory_id', '')">SELECTED</dtml-if> + >&dtml-title_or_id;</option> + </dtml-in> + </select> +</td> +</tr> +</dtml-if> + <tr> <th align="left">'Manager' role bypasses guards</th> <td> diff --git a/product/ERP5Type/patches/DCWorkflow.py b/product/ERP5Type/patches/DCWorkflow.py index ff4a483525..03e49eba67 100644 --- a/product/ERP5Type/patches/DCWorkflow.py +++ b/product/ERP5Type/patches/DCWorkflow.py @@ -26,6 +26,7 @@ from Products.CMFCore.utils import _getAuthenticatedUser from DocumentTemplate.DT_Util import TemplateDict from DateTime import DateTime from Products.ERP5Type.Cache import CachingMethod +from Products.ERP5Type.Cache import DEFAULT_CACHE_FACTORY from Products.ERP5Type.Utils import convertToMixedCase from string import join from zLOG import LOG @@ -36,14 +37,16 @@ from zLOG import LOG from Products.DCWorkflow.WorkflowUIMixin import WorkflowUIMixin as WorkflowUIMixin_class from Products.DCWorkflow.Guard import Guard -def WorkflowUIMixin_setProperties( self, title - , description='' # the only addition to WorkflowUIMixin.setProperties - , manager_bypass=0, props=None, REQUEST=None): +# patched to add a description on worklist for ERP5 Web, and to add the cache +# control for worklists +def WorkflowUIMixin_setProperties( self, title, description='', + cache_factory_id='', manager_bypass=0, props=None, REQUEST=None): """Sets basic properties. """ self.title = str(title) self.description = str(description) self.manager_bypass = manager_bypass and 1 or 0 + self.cache_factory_id = cache_factory_id g = Guard() if g.changeFromProperties(props or REQUEST): self.creation_guard = g @@ -57,6 +60,7 @@ WorkflowUIMixin_class.setProperties = WorkflowUIMixin_setProperties WorkflowUIMixin_class.manage_properties = DTMLFile('workflow_properties', _dtmldir) +DCWorkflowDefinition_listGlobalActions_original = DCWorkflowDefinition.listGlobalActions def DCWorkflowDefinition_listGlobalActions(self, info): ''' @@ -65,11 +69,12 @@ def DCWorkflowDefinition_listGlobalActions(self, info): Called on every request. Returns the actions to be displayed to the user. ''' + if not self.worklists: + return None # Optimization + + portal = self._getPortalRoot() def _listGlobalActions(user=None, id=None, portal_path=None): - if not self.worklists: - return None # Optimization sm = getSecurityManager() - portal = self._getPortalRoot() res = [] fmt_data = None # We want to display some actions depending on the current date @@ -96,7 +101,6 @@ def DCWorkflowDefinition_listGlobalActions(self, info): if not (guard is None or guard.check(sm, self, portal)): dict['local_roles'] = guard.roles # Patch to use ZSQLCatalog and get high speed - # LOG("PatchedDCWorkflowDefinition", 0, dict) searchres_len = int(apply(catalog.countResults, (), dict)[0][0]) if searchres_len == 0: continue @@ -121,11 +125,17 @@ def DCWorkflowDefinition_listGlobalActions(self, info): res.sort() return map((lambda (id, val): val), res) - # Return Cache - _listGlobalActions = CachingMethod(_listGlobalActions, id='listGlobalActions', cache_duration = 300) - user = str(_getAuthenticatedUser(self)) - return _listGlobalActions(user=user, id=self.id, portal_path=self._getPortalRoot().getPhysicalPath()) - + cache_tool = getToolByName(self, 'portal_caches', None) + if cache_tool is not None: + # If we have a cache factory controlling this workflow's worklist cache + cache_factory = getattr(self, 'cache_factory_id', DEFAULT_CACHE_FACTORY) + _listGlobalActions = CachingMethod(_listGlobalActions, + id='%s_listGlobalActions' % self.id, + cache_factory=cache_factory) + user = str(_getAuthenticatedUser(self)) + return _listGlobalActions(user=user, portal_path=portal.getPhysicalPath()) + else: + return DCWorkflowDefinition_listGlobalActions_original(self, info) DCWorkflowDefinition.listGlobalActions = DCWorkflowDefinition_listGlobalActions diff --git a/product/ERP5Type/tests/testCacheTool.py b/product/ERP5Type/tests/testCacheTool.py index 95d743a5d7..9ea774ad8b 100644 --- a/product/ERP5Type/tests/testCacheTool.py +++ b/product/ERP5Type/tests/testCacheTool.py @@ -282,6 +282,44 @@ return result ## Cache cleared shouldn't be previously cached self.assert_(1.0 < calculation_time) + def test_DCWorkflowIntegration(self, quiet=0, run=run_all_test): + """ Test Wokflow caching DCWorkflow global actions""" + portal = self.getPortal() + # set up caching environnement + ctool = portal.portal_caches + first_factory = ctool.newContent(portal_type='Cache Factory', + id='first_factory') + first_factory_cache = TestingCache({}) + second_factory = ctool.newContent(portal_type='Cache Factory', + id='second_factory') + second_factory_cache = TestingCache({}) + # emulate CachingMethod.factories initialization + CachingMethod.factories['first_factory'] = first_factory_cache + CachingMethod.factories['second_factory'] = second_factory_cache + + # setup two workflows with different cache factories + wftool = portal.portal_workflow + wftool.manage_addWorkflow('erp5_workflow (ERP5-style empty workflow)', + 'first_workflow') + first_workflow = wftool._getOb('first_workflow') + first_workflow.cache_factory_id = 'first_factory' + first_workflow.worklists.addWorklist('dummy_worklist') + + wftool.manage_addWorkflow('erp5_workflow (ERP5-style empty workflow)', + 'second_workflow') + second_workflow = wftool._getOb('second_workflow') + second_workflow.cache_factory_id = 'second_factory' + second_workflow.worklists.addWorklist('dummy_worklist') + + # listing actions will use the corresponding cache + info = wftool._getOAI(ctool) + first_workflow.listGlobalActions(info) + self.assertEquals(1, first_factory_cache.getCacheMisses()) + self.assertEquals(0, second_factory_cache.getCacheMisses()) + second_workflow.listGlobalActions(info) + self.assertEquals(1, first_factory_cache.getCacheMisses()) + self.assertEquals(1, second_factory_cache.getCacheMisses()) + if __name__ == '__main__': framework() else: -- 2.30.9