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):
alarm = getattr(self.portal.portal_alarms, 'upgrader_check_post_upgrade')
active_process = alarm.getLastActiveProcess()
detail_list = active_process.getResultList()[0].detail
message = 'Preference - Expected: edit_workflow, preference_workflow <> Found: (Default)'
self.assertTrue(message in detail_list, detail_list)
message = 'Preference - Expected: edit_workflow, preference_interaction_workflow, preference_workflow <> Found: (Default)'
self.assertIn(message, detail_list)
self.assertTrue(detail_list.count(message), 1)
def stepSetConstraintInPersonModulePortalType(self, sequence=None):
......
......@@ -133,7 +133,7 @@
</chain>
<chain>
<type>Preference</type>
<workflow>edit_workflow, preference_workflow</workflow>
<workflow>edit_workflow, preference_interaction_workflow, preference_workflow</workflow>
</chain>
<chain>
<type>Property Existence Constraint</type>
......@@ -169,7 +169,7 @@
</chain>
<chain>
<type>System Preference</type>
<workflow>edit_workflow, preference_workflow</workflow>
<workflow>edit_workflow, preference_interaction_workflow, preference_workflow</workflow>
</chain>
<chain>
<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
Module Component | edit_workflow
Predicate | edit_workflow
Preference | edit_workflow
Preference | preference_interaction_workflow
Preference | preference_workflow
Property Existence Constraint | dynamic_class_generation_interaction_workflow
Property Sheet Tool | dynamic_class_generation_interaction_workflow
......@@ -55,6 +56,7 @@ SQL Method | edit_workflow
Standard Property | dynamic_class_generation_interaction_workflow
String Attribute Match Constraint | dynamic_class_generation_interaction_workflow
System Preference | edit_workflow
System Preference | preference_interaction_workflow
System Preference | preference_workflow
TALES Constraint | dynamic_class_generation_interaction_workflow
Test Component | component_validation_workflow
......
......@@ -6,6 +6,7 @@ distributed_ram_cache_interaction_workflow
dynamic_class_generation_interaction_workflow
edit_workflow
memcached_plugin_interaction_workflow
preference_interaction_workflow
preference_workflow
pricing_interaction_workflow
rule_validation_workflow
......
......@@ -100,8 +100,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
def _clearCache(self):
self.portal.portal_caches.clearCache(
cache_factory_list=('erp5_ui_short', # for preference cache
'erp5_content_short', # for authentication cache
cache_factory_list=('erp5_content_short', # for authentication cache
))
def _getPasswordEventList(self, login):
......
......@@ -99,11 +99,10 @@ class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
is using appropriate editor (editor) as defined
in preferences
"""
self.getDefaultSitePreference().setPreferredTextEditor(preferred_editor)
if self.getDefaultSitePreference().getPreferenceState() == 'global':
self.getDefaultSitePreference()._clearCache()
else:
self.getDefaultSitePreference().enable()
site_preference = self.getDefaultSitePreference()
site_preference.setPreferredTextEditor(preferred_editor)
if site_preference.getPreferenceState() != 'global':
site_preference.enable()
# commit transaction, are preferences are in transaction cache
self.commit()
......
......@@ -66,32 +66,3 @@ class Preference( Folder ):
security = ClassSecurityInfo()
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):
self.assertEqual(list(pref_tool.getPreference(
'preferred_accounting_transaction_simulation_state_list')),
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
self.getWorkflowTool().doActionFor(person1,
'disable_action', wf_id='preference_workflow')
......@@ -526,6 +532,8 @@ class TestPreferences(PropertySheetTestCase):
# But they can see others
system_pref.view()
# check accessors works
self.assertEqual(['http://127.0.0.1'],
preference_tool.getPreferredDocumentConversionServerUrlList())
system_pref.setPreferredDocumentConversionServerUrlList(['http://1.2.3.4'])
self.tic()
self.assertEqual(['http://1.2.3.4'],
......@@ -706,8 +714,7 @@ class TestPreferences(PropertySheetTestCase):
# simulate situation when _clearCache does nothing, for example in case
# if memcached or any other non-deleteable cache is used
from Products.ERP5Form.Document.Preference import Preference
Preference._clearCache = lambda *args,**kwargs: None
raise NotImplementedError("do something to simulate cache disabled")
system_preference = portal_preferences.newContent(portal_type='System Preference',
dummystring=system_preference_string)
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