From aac0a994a2c314e0e639c5db3b7055dd8e3d2c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Calonne?= <aurel@nexedi.com> Date: Tue, 25 Aug 2015 12:19:28 +0000 Subject: [PATCH] budget : move the class definition of cell from script to code Using an instance of the class from the script create a huge memory leak in zope which does not happen when instanciating class from the code. The issue seems to come from the use by the matribox as simple test cases of instanciation from script do not reproduce the memory leak --- .../BudgetLine_getAvailableBudgetCell.xml | 84 ------------------- .../BudgetLine_getConsumedBudgetCell.xml | 84 ------------------- .../BudgetLine_getEngagedBudgetCell.xml | 84 ------------------- .../matrixbox.xml | 2 +- .../matrixbox_quantity.xml | 2 +- .../matrixbox.xml | 2 +- .../matrixbox.xml | 2 +- product/ERP5/Document/BudgetLine.py | 45 ++++++++++ 8 files changed, 49 insertions(+), 256 deletions(-) delete mode 100644 bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getAvailableBudgetCell.xml delete mode 100644 bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getConsumedBudgetCell.xml delete mode 100644 bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getEngagedBudgetCell.xml diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getAvailableBudgetCell.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getAvailableBudgetCell.xml deleted file mode 100644 index a86684ccc8..0000000000 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getAvailableBudgetCell.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?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>_body</string> </key> - <value> <string>from ZTUtils import make_query\n -\n -def getFakeBudgetCell(amount):\n - class FakeBudgetCell:\n - def getAvailableBudget(self):\n - return amount\n - def getExplanationUrl(self, *args, **w):\n - return \'%s/BudgetLine_viewConsumedBudgetMovementList?%s\' % (\n - context.absolute_url(),\n - make_query(dict(cell_index=list(cell_index), engaged_budget=True)))\n - return FakeBudgetCell()\n -\n -try:\n - available_budget_dict = container.REQUEST.other[script.getId()]\n -except KeyError:\n - available_budget_dict = container.REQUEST.other[script.getId()] = context.getAvailableBudgetDict()\n -\n -return getFakeBudgetCell(available_budget_dict.get(cell_index))\n -</string> </value> - </item> - <item> - <key> <string>_params</string> </key> - <value> <string>*cell_index, **kw</string> </value> - </item> - <item> - <key> <string>id</string> </key> - <value> <string>BudgetLine_getAvailableBudgetCell</string> </value> - </item> - </dictionary> - </pickle> - </record> -</ZopeData> diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getConsumedBudgetCell.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getConsumedBudgetCell.xml deleted file mode 100644 index 11c8878aa5..0000000000 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getConsumedBudgetCell.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?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>_body</string> </key> - <value> <string>from ZTUtils import make_query\n -\n -def getFakeBudgetCell(amount):\n - class FakeBudgetCell:\n - def getConsumedBudget(self):\n - return amount\n - def getExplanationUrl(self, *args, **w):\n - return \'%s/BudgetLine_viewConsumedBudgetMovementList?%s\' % (\n - context.absolute_url(),\n - make_query(dict(cell_index=list(cell_index), engaged_budget=False)))\n - return FakeBudgetCell()\n -\n -try:\n - consumed_budget_dict = container.REQUEST.other[script.getId()]\n -except KeyError:\n - consumed_budget_dict = container.REQUEST.other[script.getId()] = context.getConsumedBudgetDict()\n -\n -return getFakeBudgetCell(consumed_budget_dict.get(cell_index))\n -</string> </value> - </item> - <item> - <key> <string>_params</string> </key> - <value> <string>*cell_index, **kw</string> </value> - </item> - <item> - <key> <string>id</string> </key> - <value> <string>BudgetLine_getConsumedBudgetCell</string> </value> - </item> - </dictionary> - </pickle> - </record> -</ZopeData> diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getEngagedBudgetCell.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getEngagedBudgetCell.xml deleted file mode 100644 index c431887c68..0000000000 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_getEngagedBudgetCell.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?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>_body</string> </key> - <value> <string>from ZTUtils import make_query\n -\n -def getFakeBudgetCell(amount):\n - class FakeBudgetCell:\n - def getEngagedBudget(self):\n - return amount\n - def getExplanationUrl(self, *args, **w):\n - return \'%s/BudgetLine_viewConsumedBudgetMovementList?%s\' % (\n - context.absolute_url(),\n - make_query(dict(cell_index=list(cell_index), engaged_budget=True)))\n - return FakeBudgetCell()\n -\n -try:\n - engaged_budget_dict = container.REQUEST.other[script.getId()]\n -except KeyError:\n - engaged_budget_dict = container.REQUEST.other[script.getId()] = context.getEngagedBudgetDict()\n -\n -return getFakeBudgetCell(engaged_budget_dict.get(cell_index))\n -</string> </value> - </item> - <item> - <key> <string>_params</string> </key> - <value> <string>*cell_index, **kw</string> </value> - </item> - <item> - <key> <string>id</string> </key> - <value> <string>BudgetLine_getEngagedBudgetCell</string> </value> - </item> - </dictionary> - </pickle> - </record> -</ZopeData> diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox.xml index 6b03dc46de..f3b8c3125d 100644 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox.xml +++ b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox.xml @@ -81,7 +81,7 @@ </item> <item> <key> <string>cell_getter_method</string> </key> - <value> <string>BudgetLine_getAvailableBudgetCell</string> </value> + <value> <string>getAvailableBudgetCell</string> </value> </item> <item> <key> <string>editable_attributes</string> </key> diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox_quantity.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox_quantity.xml index 3c1c53e649..ac0fbb3516 100644 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox_quantity.xml +++ b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewAvailableBudget/matrixbox_quantity.xml @@ -112,7 +112,7 @@ <dictionary> <item> <key> <string>_text</string> </key> - <value> <string>python: cell.getAvailableBudget()</string> </value> + <value> <string>cell/getAvailableBudget</string> </value> </item> </dictionary> </pickle> diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewConsumedBudget/matrixbox.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewConsumedBudget/matrixbox.xml index 7f6aaa8e87..9607d34045 100644 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewConsumedBudget/matrixbox.xml +++ b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewConsumedBudget/matrixbox.xml @@ -81,7 +81,7 @@ </item> <item> <key> <string>cell_getter_method</string> </key> - <value> <string>BudgetLine_getConsumedBudgetCell</string> </value> + <value> <string>getConsumedBudgetCell</string> </value> </item> <item> <key> <string>editable_attributes</string> </key> diff --git a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewEngagedBudget/matrixbox.xml b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewEngagedBudget/matrixbox.xml index c5b679f61a..f474c2192b 100644 --- a/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewEngagedBudget/matrixbox.xml +++ b/bt5/erp5_budget/SkinTemplateItem/portal_skins/erp5_budget/BudgetLine_viewEngagedBudget/matrixbox.xml @@ -81,7 +81,7 @@ </item> <item> <key> <string>cell_getter_method</string> </key> - <value> <string>BudgetLine_getEngagedBudgetCell</string> </value> + <value> <string>getEngagedBudgetCell</string> </value> </item> <item> <key> <string>editable_attributes</string> </key> diff --git a/product/ERP5/Document/BudgetLine.py b/product/ERP5/Document/BudgetLine.py index 43f620a6c9..417a086510 100644 --- a/product/ERP5/Document/BudgetLine.py +++ b/product/ERP5/Document/BudgetLine.py @@ -34,6 +34,30 @@ from Products.ERP5Type.XMLMatrix import XMLMatrix from Products.ERP5Type.Core.Predicate import Predicate from Products.ERP5.mixin.variated import VariatedMixin from Products.ERP5Type.Cache import transactional_cached +from ZTUtils import make_query + +class TempBudgetCell: + __slots__ = ('amount', 'cell_index', 'url', 'engaged_budget') + def __init__(self, amount, cell_index, url, engaged_budget): + self.amount = amount + self.cell_index = cell_index + self.url = url + self.engaged_budget = engaged_budget + + def getConsumedBudget(self): + return self.amount + + def getAvailableBudget(self): + return self.amount + + def getEngagedBudget(self): + return self.amount + + def getExplanationUrl(self, *args, **w): + return '%s/BudgetLine_viewConsumedBudgetMovementList?%s' % ( + self.url, + make_query(dict(cell_index=list(self.cell_index), engaged_budget=self.engaged_budget))) + class BudgetLine(Predicate, XMLMatrix, VariatedMixin): """ A Line of budget, variated in budget cells. @@ -58,6 +82,7 @@ class BudgetLine(Predicate, XMLMatrix, VariatedMixin): meta_type='ERP5 Budget Line' portal_type='Budget Line' add_permission = Permissions.AddPortalContent + __allow_access_to_unprotected_subobjects__ = 1 # Declarative security security = ClassSecurityInfo() @@ -136,3 +161,23 @@ class BudgetLine(Predicate, XMLMatrix, VariatedMixin): return budget_dict + security.declareProtected(Permissions.AccessContentsInformation, + 'getConsumedBudgetCell') + def getConsumedBudgetCell(self, *cell_index, **kw): + consumed_budget_dict = self.getConsumedBudgetDict() + return TempBudgetCell(consumed_budget_dict.get(cell_index), + cell_index, self.absolute_url(), False) + + security.declareProtected(Permissions.AccessContentsInformation, + 'getAvailableBudgetCell') + def getAvailableBudgetCell(self, *cell_index, **kw): + available_budget_dict = self.getAvailableBudgetDict() + return TempBudgetCell(available_budget_dict.get(cell_index), + cell_index, self.absolute_url(), True) + + security.declareProtected(Permissions.AccessContentsInformation, + 'getEngagedBudgetCell') + def getEngagedBudgetCell(self, *cell_index, **kw): + engaged_budget_dict = self.getEngagedBudgetDict() + return TempBudgetCell(engaged_budget_dict.get(cell_index), + cell_index, self.absolute_url(), True) -- 2.30.9