Commit 671a83f6 authored by Tatuya Kamada's avatar Tatuya Kamada

reindex: Fix duplicate reindex in Supply and Delivery when more than >100 lines.

[Before]:

Where:

  in Supply or Delivery(Sale Order, Sale Packing List,..)

When:

( document.edit(something=some_value)

  OR

  document.validate(), document.start() something when workflow transition  )

AND

  document contains more than 100 sub objects, like 100 lines.

Then:
  /some_module/document/1/recursiveImmediateReindexObject
  /some_module/document/1/reindexObject
  /some_module/document/1/1/recursiveImmediateReindexObject
  .
  .
  /some_module/document/1/100/recursiveImmediateReindexObject

are triggered.

The first big recursiveImmediateReindexObject recursively reindex all the sub
objects. Thus the following reindex are duplicated.

[After]:

Reindex:
  /some_module/document/1/reindexObject
  /some_module/document/1/1/recursiveImmediateReindexObject
  .
  .
  /some_module/document/1/100/recursiveImmediateReindexObject

The root recursiveImmediateReindexObject is removed.

This has been the expected behavior from the beginning.
Before was only a side effect by giving empty dict to "if activate_kw == None"
expression.
parent aaeed09f
...@@ -33,6 +33,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase ...@@ -33,6 +33,8 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import reindex from Products.ERP5Type.tests.utils import reindex
from Products.ERP5Type.tests.utils import SubcontentReindexingWrapper from Products.ERP5Type.tests.utils import SubcontentReindexingWrapper
from DateTime import DateTime from DateTime import DateTime
from Products.ERP5Type.tests.backportUnittest import expectedFailure
import transaction
class TestSupplyMixin: class TestSupplyMixin:
def getBusinessTemplateList(self): def getBusinessTemplateList(self):
...@@ -587,6 +589,78 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper, ...@@ -587,6 +589,78 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
preference.setPreferredPricingOptimise(False) preference.setPreferredPricingOptimise(False)
self._clearCache() self._clearCache()
def _createTwoHundredSupplyLineInASupply(self):
supply = self._makeSupply(
start_date_range_min='2014/01/01',
start_date_range_max='2014/01/31',
)
for i in range(200):
resource_value = self.portal.product_module['%s_%d' % (self.id(), i)]
supply_line = self._makeSupplyLine(supply)
supply_line.edit(resource_value=resource_value,
base_price=100)
return supply
def _createTwoHundredResource(self):
for i in range(200):
self._makeResource('%s_%d' % (self.id(), i))
def testReindexOnLargeSupply(self):
"""
Make sure that recursiveImmediateReindexObject is not called on the root
document when the document has more than 100 sub objects.
"""
self._makeSections()
self._createTwoHundredResource()
supply = self._createTwoHundredSupplyLineInASupply()
# First, clear activities just in case.
self.tic()
# Editing triggers reindexObject(active_kw={}) through DCWorkflowDefinition.
# Not only edit(), but also all the workflow transitions can trigger it.
# Likewise, recursiveReindexObject(active_kw={}) is triggered, for instance
# in Supply.py, Delivery.py and etc,.
# This is because of the reindexObject() method definition on the Documents.
supply.edit(title='xx')
transaction.commit()
sql_connection = self.getSQLConnection()
supply_path = supply.getPath()
sql = """SELECT
count(*)
FROM
message
WHERE
path like '%s'
AND
method_id = 'recursiveImmediateReindexObject'
""" % (supply_path.replace('_', r'\_') + '/%')
result = sql_connection.manage_test(sql)
all_the_spply_line_activities_count = result[0]['COUNT(*)']
# supply line reindex activity count must be 200 since created 200 lines
self.assertEqual(200, all_the_spply_line_activities_count)
sql_connection = self.getSQLConnection()
sql = "SELECT count(*) FROM message WHERE path='%s'" % supply_path
result = sql_connection.manage_test(sql)
supply_document_reindex_count = result[0]['COUNT(*)']
# reindex activity with the same supply must be only one in this case.
self.assertEqual(1, supply_document_reindex_count)
sql = "SELECT count(*) FROM message WHERE path='%s' AND method_id='%s'" \
% (supply_path, 'recursiveImmediateReindexObject')
result = sql_connection.manage_test(sql)
supply_recursive_immediate_reindex_count = result[0]['COUNT(*)']
# the count of recursiveImmediateReindex on Supply document must be zero
# because the supply contains >100 sub objects. And the the suply lines
# reindex are already triggerred. Thus if recursiveImmediateReindex
# is also triggered on Supply, the reindex will be duplicated. Moreover,
# recursiveImmediateReindex in a single node is less efficient comparing
# to use all nodes for the reindex, in such a >100 case.
self.assertEqual(0, supply_recursive_immediate_reindex_count)
class TestPurchaseSupply(TestSaleSupply): class TestPurchaseSupply(TestSaleSupply):
""" """
Test Purchase Supplies usage Test Purchase Supplies usage
......
...@@ -1292,7 +1292,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn): ...@@ -1292,7 +1292,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
"""Recursively indexes the content of self. """Recursively indexes the content of self.
""" """
if self.isIndexable: if self.isIndexable:
if activate_kw is None and self.objectCount() > REINDEX_SPLIT_COUNT: if not activate_kw and self.objectCount() > REINDEX_SPLIT_COUNT:
# If the number of objects to reindex is too high # If the number of objects to reindex is too high
# we should try to split reindexing in order to be more efficient # we should try to split reindexing in order to be more efficient
# NOTE: this heuristic will fail for example with orders which # NOTE: this heuristic will fail for example with orders which
......
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