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