Commit 622838ef authored by Romain Courteaud's avatar Romain Courteaud

erp5_core: ensure Base_reindexAndSenseAlarm never end without calling the alarm

parent 007de00c
......@@ -349,6 +349,41 @@ class TestBase_reindexAndSenseAlarm(ERP5TypeTestCase):
alarm.workflow_history['edit_workflow'][-1]['comment']
)
def test_reindexAndSenseAlarm_manyContextSameTransaction(self):
# Check that the script wait for the alarm to be not activate
# before triggering it again
alarm = self.portal.portal_alarms.invoice_builder_alarm
workflow_history_count = len(alarm.workflow_history['edit_workflow'])
document_list = []
for doc in self.portal.contentValues():
if doc.getId().endswith('_module'):
document_list.append((doc, self.getIndexationDate(doc)))
doc.Base_reindexAndSenseAlarm(['invoice_builder_alarm'])
# Sadly, catalog indexation timestamp has a second precision
# It is needed to wait this 1 second to be able to verify new indexation
sleep(1)
with TemporaryAlarmScript(alarm, 'Alarm_buildInvoice'):
self.tic()
edit_timestamp = alarm.getModificationDate()
for doc, previous_indexation_timestamp in document_list:
next_indexation_timestamp = self.getIndexationDate(doc)
# check that the document has been reindexed
self.assertLessThan(previous_indexation_timestamp, next_indexation_timestamp)
# check that alarm was called after the object was reindexed
self.assertLessThan(next_indexation_timestamp, edit_timestamp)
self.assertEqual(
len(alarm.workflow_history['edit_workflow']),
workflow_history_count + 1
)
self.assertEqual(
'Visited by Alarm_buildInvoice',
alarm.workflow_history['edit_workflow'][-1]['comment']
)
def test_reindexAndSenseAlarm_twoContextDifferentTransaction(self):
# Check that the script wait for the alarm to be not activate
# before triggering it again
......@@ -434,3 +469,39 @@ class TestBase_reindexAndSenseAlarm(ERP5TypeTestCase):
'Visited by Alarm_buildPackingList',
alarm2.workflow_history['edit_workflow'][-1]['comment']
)
def test_reindexAndSenseAlarm_concurrentNode(self):
# No idea how to reproduce multiple zope nodes handling
# many activity, try to fake found problem
# Ensure Base_reindexAndSenseAlarm never completely drop itself
# from activities
alarm_tool = self.portal.portal_alarms
alarm = alarm_tool.invoice_builder_alarm
workflow_history_count = len(alarm.workflow_history['edit_workflow'])
deduplication_tag = 'Base_reindexAndSenseAlarm_%s' % alarm.getId()
wait_tag = 'wait_tag'
alarm_tool.activate(
activity='SQLQueue',
tag=wait_tag
).getId()
alarm_tool.activate(
activity='SQLQueue',
tag=deduplication_tag,
after_tag=wait_tag
).getId()
alarm_tool.activate(
tag=deduplication_tag
).Base_reindexAndSenseAlarm([alarm.getId()], must_reindex_context=False)
with TemporaryAlarmScript(alarm, 'Alarm_buildInvoice'):
self.tic()
self.assertEqual(
len(alarm.workflow_history['edit_workflow']),
workflow_history_count + 1
)
self.assertEqual(
'Visited by Alarm_buildInvoice',
alarm.workflow_history['edit_workflow'][-1]['comment']
)
......@@ -34,22 +34,21 @@ if alarm_tool.isSubscribed() and len(alarm_id_list):
alarm_tool.activate(**activate_kw).Base_reindexAndSenseAlarm([alarm_id],
must_reindex_context=False)
elif portal.portal_activities.countMessageWithTag(deduplication_tag) <= 1:
if alarm.isActive():
# If the alarm is active, wait for it
# and try to reduce the number of activities
# to reduce the number of alarm execution
activate_kw = {}
activate_kw['activity'] = 'SQLQueue'
activate_kw['priority'] = PRIORITY
activate_kw['tag'] = deduplication_tag
activate_kw['after_path'] = alarm.getPath()
# Wait for the previous alarm run to be finished
# call on alarm tool to gather and drop with sqldict
alarm_tool.activate(**activate_kw).Base_reindexAndSenseAlarm([alarm_id],
must_reindex_context=False)
else:
# activeSense create an activity in SQLDict
alarm.activeSense()
# Prevent 2 nodes to call activateSense concurrently
alarm.serialize()
elif alarm.isActive() or (1 < portal.portal_activities.countMessageWithTag(deduplication_tag)):
# If the alarm is active, wait for it
# and try to reduce the number of activities
# to reduce the number of alarm execution
activate_kw = {}
activate_kw['activity'] = 'SQLDict'
activate_kw['priority'] = PRIORITY
activate_kw['tag'] = deduplication_tag
activate_kw['after_path'] = alarm.getPath()
# Wait for the previous alarm run to be finished
# call on alarm tool to gather and drop with sqldict
alarm_tool.activate(**activate_kw).Base_reindexAndSenseAlarm([alarm_id],
must_reindex_context=False)
else:
# activeSense create an activity in SQLDict
alarm.activeSense()
# Prevent 2 nodes to call activateSense concurrently
alarm.serialize()
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