Commit 3e558ff9 authored by Jérome Perrin's avatar Jérome Perrin

preferences: use an interaction workflow to clear cache

When we use preference.edit(preferred_something=something_else) the
cache was cleared, because there is an interaction on _edit, but when we
do preference.setPreferredSomething(something_else) cache was not
cleared.

This still have a problem cache is cleared too much but at least it
eliminates this incorrect behavior.

Update tests at the same time:
 - testEditorField,testAuthenticationPolicy: no need to clear cache,
   it's now done automatically.
 - testUpgrader: the workflow chain of preference changed. This test is
   asserting the actual workflow chain, so we have to update the test
   everytime workflow chain is modified.
parent f940f234
...@@ -232,8 +232,8 @@ class TestUpgrader(ERP5TypeTestCase): ...@@ -232,8 +232,8 @@ class TestUpgrader(ERP5TypeTestCase):
alarm = getattr(self.portal.portal_alarms, 'upgrader_check_post_upgrade') alarm = getattr(self.portal.portal_alarms, 'upgrader_check_post_upgrade')
active_process = alarm.getLastActiveProcess() active_process = alarm.getLastActiveProcess()
detail_list = active_process.getResultList()[0].detail detail_list = active_process.getResultList()[0].detail
message = 'Preference - Expected: edit_workflow, preference_workflow <> Found: (Default)' message = 'Preference - Expected: edit_workflow, preference_interaction_workflow, preference_workflow <> Found: (Default)'
self.assertTrue(message in detail_list, detail_list) self.assertIn(message, detail_list)
self.assertTrue(detail_list.count(message), 1) self.assertTrue(detail_list.count(message), 1)
def stepSetConstraintInPersonModulePortalType(self, sequence=None): def stepSetConstraintInPersonModulePortalType(self, sequence=None):
......
...@@ -133,7 +133,7 @@ ...@@ -133,7 +133,7 @@
</chain> </chain>
<chain> <chain>
<type>Preference</type> <type>Preference</type>
<workflow>edit_workflow, preference_workflow</workflow> <workflow>edit_workflow, preference_interaction_workflow, preference_workflow</workflow>
</chain> </chain>
<chain> <chain>
<type>Property Existence Constraint</type> <type>Property Existence Constraint</type>
...@@ -169,7 +169,7 @@ ...@@ -169,7 +169,7 @@
</chain> </chain>
<chain> <chain>
<type>System Preference</type> <type>System Preference</type>
<workflow>edit_workflow, preference_workflow</workflow> <workflow>edit_workflow, preference_interaction_workflow, preference_workflow</workflow>
</chain> </chain>
<chain> <chain>
<type>TALES Constraint</type> <type>TALES Constraint</type>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionWorkflowDefinition" module="Products.ERP5.InteractionWorkflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>preference_interaction_workflow</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Interaction" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interactions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>ERP5Site_clearPreferrenceCache</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>_set.*</string>
<string>manage_beforeDelete</string>
<string>enable</string>
<string>disable</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Scripts" module="Products.DCWorkflow.Scripts"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>scripts</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Clear caches used by methods of this preference
# TODO: clear different caches according to the preference priority
# TODO: (XXX) currently, if one use enables / disables a cache, caches
for all other users are reset. This is not good for a system
in which users do a lot of preference validation. A better solution
is needed for this. But it is not easy because the concept of
"per user cache" has been proven to be ambiguous or useless.
In theory, a solution could consist in using more keys to
select caches or to delete "manually" certain cache keys.
"""
portal = sci['object'].getPortalObject()
portal.portal_caches.clearCache(cache_factory_list=('erp5_ui_short',))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>sci</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_clearPreferrenceCache</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Variables" module="Products.DCWorkflow.Variables"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variables</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklists" module="Products.DCWorkflow.Worklists"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklists</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -45,6 +45,7 @@ Module Component | dynamic_class_generation_interaction_workflow ...@@ -45,6 +45,7 @@ Module Component | dynamic_class_generation_interaction_workflow
Module Component | edit_workflow Module Component | edit_workflow
Predicate | edit_workflow Predicate | edit_workflow
Preference | edit_workflow Preference | edit_workflow
Preference | preference_interaction_workflow
Preference | preference_workflow Preference | preference_workflow
Property Existence Constraint | dynamic_class_generation_interaction_workflow Property Existence Constraint | dynamic_class_generation_interaction_workflow
Property Sheet Tool | dynamic_class_generation_interaction_workflow Property Sheet Tool | dynamic_class_generation_interaction_workflow
...@@ -55,6 +56,7 @@ SQL Method | edit_workflow ...@@ -55,6 +56,7 @@ SQL Method | edit_workflow
Standard Property | dynamic_class_generation_interaction_workflow Standard Property | dynamic_class_generation_interaction_workflow
String Attribute Match Constraint | dynamic_class_generation_interaction_workflow String Attribute Match Constraint | dynamic_class_generation_interaction_workflow
System Preference | edit_workflow System Preference | edit_workflow
System Preference | preference_interaction_workflow
System Preference | preference_workflow System Preference | preference_workflow
TALES Constraint | dynamic_class_generation_interaction_workflow TALES Constraint | dynamic_class_generation_interaction_workflow
Test Component | component_validation_workflow Test Component | component_validation_workflow
......
...@@ -6,6 +6,7 @@ distributed_ram_cache_interaction_workflow ...@@ -6,6 +6,7 @@ distributed_ram_cache_interaction_workflow
dynamic_class_generation_interaction_workflow dynamic_class_generation_interaction_workflow
edit_workflow edit_workflow
memcached_plugin_interaction_workflow memcached_plugin_interaction_workflow
preference_interaction_workflow
preference_workflow preference_workflow
pricing_interaction_workflow pricing_interaction_workflow
rule_validation_workflow rule_validation_workflow
......
...@@ -100,8 +100,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase): ...@@ -100,8 +100,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
def _clearCache(self): def _clearCache(self):
self.portal.portal_caches.clearCache( self.portal.portal_caches.clearCache(
cache_factory_list=('erp5_ui_short', # for preference cache cache_factory_list=('erp5_content_short', # for authentication cache
'erp5_content_short', # for authentication cache
)) ))
def _getPasswordEventList(self, login): def _getPasswordEventList(self, login):
......
...@@ -99,11 +99,10 @@ class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -99,11 +99,10 @@ class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
is using appropriate editor (editor) as defined is using appropriate editor (editor) as defined
in preferences in preferences
""" """
self.getDefaultSitePreference().setPreferredTextEditor(preferred_editor) site_preference = self.getDefaultSitePreference()
if self.getDefaultSitePreference().getPreferenceState() == 'global': site_preference.setPreferredTextEditor(preferred_editor)
self.getDefaultSitePreference()._clearCache() if site_preference.getPreferenceState() != 'global':
else: site_preference.enable()
self.getDefaultSitePreference().enable()
# commit transaction, are preferences are in transaction cache # commit transaction, are preferences are in transaction cache
self.commit() self.commit()
......
...@@ -66,32 +66,3 @@ class Preference( Folder ): ...@@ -66,32 +66,3 @@ class Preference( Folder ):
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
def _clearCache(self):
"""Clear caches used by methods of this preference
# TODO: clear different caches according to the preference priority
# TODO: (XXX) currently, if one use enables / disables a cache, caches
for all other users are reset. This is not good for a system
in which users do a lot of preference validation. A better solution
is needed for this. But it is not easy because the concept of
"per user cache" has been proven to be ambiguous or useless.
In theory, a solution could consist in using more keys to
select caches or to delete "manually" certain cache keys.
"""
portal_caches = getToolByName(self.getPortalObject(), 'portal_caches')
portal_caches.clearCache(cache_factory_list=('erp5_ui_short',))
def _edit(self, **kw):
"""edit and clear all caches"""
self._clearCache()
Folder._edit(self, **kw)
security.declareProtected(Permissions.ModifyPortalContent, 'enable')
def enable(self, **kw):
"""Workflow method"""
self._clearCache()
security.declareProtected(Permissions.ModifyPortalContent, 'disable')
def disable(self, **kw):
"""Workflow method"""
self._clearCache()
...@@ -217,6 +217,12 @@ class TestPreferences(PropertySheetTestCase): ...@@ -217,6 +217,12 @@ class TestPreferences(PropertySheetTestCase):
self.assertEqual(list(pref_tool.getPreference( self.assertEqual(list(pref_tool.getPreference(
'preferred_accounting_transaction_simulation_state_list')), 'preferred_accounting_transaction_simulation_state_list')),
list(person1.getPreferredAccountingTransactionSimulationStateList())) list(person1.getPreferredAccountingTransactionSimulationStateList()))
# edits can also be made with setters
person1.setPreferredAccountingTransactionSimulationStateList(['planned'])
self.assertEqual(list(pref_tool.getPreference(
'preferred_accounting_transaction_simulation_state_list')),
list(person1.getPreferredAccountingTransactionSimulationStateList()))
# disable person -> group is selected # disable person -> group is selected
self.getWorkflowTool().doActionFor(person1, self.getWorkflowTool().doActionFor(person1,
'disable_action', wf_id='preference_workflow') 'disable_action', wf_id='preference_workflow')
...@@ -526,6 +532,8 @@ class TestPreferences(PropertySheetTestCase): ...@@ -526,6 +532,8 @@ class TestPreferences(PropertySheetTestCase):
# But they can see others # But they can see others
system_pref.view() system_pref.view()
# check accessors works # check accessors works
self.assertEqual(['http://127.0.0.1'],
preference_tool.getPreferredDocumentConversionServerUrlList())
system_pref.setPreferredDocumentConversionServerUrlList(['http://1.2.3.4']) system_pref.setPreferredDocumentConversionServerUrlList(['http://1.2.3.4'])
self.tic() self.tic()
self.assertEqual(['http://1.2.3.4'], self.assertEqual(['http://1.2.3.4'],
...@@ -706,8 +714,7 @@ class TestPreferences(PropertySheetTestCase): ...@@ -706,8 +714,7 @@ class TestPreferences(PropertySheetTestCase):
# simulate situation when _clearCache does nothing, for example in case # simulate situation when _clearCache does nothing, for example in case
# if memcached or any other non-deleteable cache is used # if memcached or any other non-deleteable cache is used
from Products.ERP5Form.Document.Preference import Preference raise NotImplementedError("do something to simulate cache disabled")
Preference._clearCache = lambda *args,**kwargs: None
system_preference = portal_preferences.newContent(portal_type='System Preference', system_preference = portal_preferences.newContent(portal_type='System Preference',
dummystring=system_preference_string) dummystring=system_preference_string)
system_preference.enable() system_preference.enable()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment