Commit a27d06f8 authored by Jérome Perrin's avatar Jérome Perrin

wip log timings

parent 1737f9e0
...@@ -20,6 +20,26 @@ from accessor_holder import AccessorHolderType ...@@ -20,6 +20,26 @@ from accessor_holder import AccessorHolderType
import persistent_migration import persistent_migration
from ZODB.POSException import ConflictError from ZODB.POSException import ConflictError
from contextlib import contextmanager
import time
import logging
@contextmanager
def _log_time_usage(prefix=""):
'''log the time usage in a code block
prefix: the prefix text to show
'''
start = time.time()
try:
yield
finally:
end = time.time()
elapsed_seconds = float("%.4f" % (end - start))
if elapsed_seconds > 0.5:
logging.critical('%s: elapsed seconds: %s', prefix, elapsed_seconds)
logging.info('%s: elapsed seconds: %s', prefix, elapsed_seconds)
class ERP5BaseBroken(Broken, ERP5Base, PersistentBroken): class ERP5BaseBroken(Broken, ERP5Base, PersistentBroken):
# PersistentBroken can't be reused directly # PersistentBroken can't be reused directly
# because its « layout differs from 'GhostPortalType' » # because its « layout differs from 'GhostPortalType' »
...@@ -269,7 +289,8 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder): ...@@ -269,7 +289,8 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder):
return getattr(cls.__bases__[0], name) return getattr(cls.__bases__[0], name)
if not name.startswith('__') and cls.__isghost__: if not name.startswith('__') and cls.__isghost__:
cls.loadClass() with _log_time_usage('loadClass (%s)' % cls):
cls.loadClass()
return getattr(cls, name) return getattr(cls, name)
raise AttributeError("'%r' has no attribute '%s'" % (cls, name)) raise AttributeError("'%r' has no attribute '%s'" % (cls, name))
...@@ -297,11 +318,12 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder): ...@@ -297,11 +318,12 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder):
# generate all methods on Base accessor holder, with all methods # generate all methods on Base accessor holder, with all methods
# returning False, and redefine on portal types only those returning True, # returning False, and redefine on portal types only those returning True,
# aka only those for the group they belong to # aka only those for the group they belong to
for group in ERP5TypeInformation.defined_group_list: if 1: #with _log_time_usage("generating isAccessors for %s" % cls):
value = cls.__name__ in site._getPortalGroupedTypeSet(group) for group in ERP5TypeInformation.defined_group_list:
accessor_name = 'is' + UpperCase(group) + 'Type' value = cls.__name__ in site._getPortalGroupedTypeSet(group)
method = ConstantGetter(accessor_name, group, value) accessor_name = 'is' + UpperCase(group) + 'Type'
cls.registerAccessor(method, Permissions.AccessContentsInformation) method = ConstantGetter(accessor_name, group, value)
cls.registerAccessor(method, Permissions.AccessContentsInformation)
from Products.ERP5Type.Cache import initializePortalCachingProperties from Products.ERP5Type.Cache import initializePortalCachingProperties
initializePortalCachingProperties(site) initializePortalCachingProperties(site)
......
...@@ -348,6 +348,24 @@ def generatePortalTypeClass(site, portal_type_name): ...@@ -348,6 +348,24 @@ def generatePortalTypeClass(site, portal_type_name):
interface_class_list, interface_class_list,
attribute_dict) attribute_dict)
from contextlib import contextmanager
import time
import logging
@contextmanager
def _log_time_usage(prefix=""):
'''log the time usage in a code block
prefix: the prefix text to show
'''
start = time.time()
try:
yield
finally:
end = time.time()
elapsed_seconds = float("%.4f" % (end - start))
logging.info('%s: elapsed seconds: %s', prefix, elapsed_seconds)
def loadTempPortalTypeClass(portal_type_name): def loadTempPortalTypeClass(portal_type_name):
""" """
Returns a class suitable for a temporary portal type Returns a class suitable for a temporary portal type
...@@ -463,33 +481,35 @@ def synchronizeDynamicModules(context, force=False): ...@@ -463,33 +481,35 @@ def synchronizeDynamicModules(context, force=False):
LOG("ERP5Type.dynamic", 0, "Resetting dynamic classes") LOG("ERP5Type.dynamic", 0, "Resetting dynamic classes")
try: try:
for _, klass in inspect.getmembers(erp5.portal_type, with _log_time_usage("Resetting dynamic classes"):
inspect.isclass):
# Zope Interface is implemented through __implements__, for _, klass in inspect.getmembers(erp5.portal_type,
# __implemented__ (both implementedBy instances) and __provides__ inspect.isclass):
# (ClassProvides instance) attributes set on the class by # Zope Interface is implemented through __implements__,
# zope.interface.declarations.implementedByFallback. # __implemented__ (both implementedBy instances) and __provides__
# # (ClassProvides instance) attributes set on the class by
# However both implementedBy and ClassProvides instances keep a # zope.interface.declarations.implementedByFallback.
# reference to the class itself, thus creating a circular references. #
for k in klass.mro(): # However both implementedBy and ClassProvides instances keep a
module_name = k.__module__ # reference to the class itself, thus creating a circular references.
if (module_name.startswith('erp5.') and for k in klass.mro():
# Components are reset independently of Portal Types classes module_name = k.__module__
not module_name.startswith('erp5.component.')): if (module_name.startswith('erp5.') and
for attr in ('__implements__', '__implemented__', '__provides__'): # Components are reset independently of Portal Types classes
if k.__dict__.get(attr) is not None: not module_name.startswith('erp5.component.')):
delattr(k, attr) for attr in ('__implements__', '__implemented__', '__provides__'):
if k.__dict__.get(attr) is not None:
klass.restoreGhostState() delattr(k, attr)
# Clear accessor holders of ZODB Property Sheets and Portal Types klass.restoreGhostState()
erp5.accessor_holder.clear()
erp5.accessor_holder.property_sheet.clear() # Clear accessor holders of ZODB Property Sheets and Portal Types
erp5.accessor_holder.clear()
for name in erp5.accessor_holder.portal_type.__dict__.keys(): erp5.accessor_holder.property_sheet.clear()
if name[0] != '_':
delattr(erp5.accessor_holder.portal_type, name) for name in erp5.accessor_holder.portal_type.__dict__.keys():
if name[0] != '_':
delattr(erp5.accessor_holder.portal_type, name)
except Exception: except Exception:
# Allow easier debugging when the code is wrong as this # Allow easier debugging when the code is wrong as this
......
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