Commit 2950c0e0 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Make registry generation of Component package thread-safe.

parent c00fc402
...@@ -73,7 +73,8 @@ class ComponentDynamicPackage(ModuleType): ...@@ -73,7 +73,8 @@ class ComponentDynamicPackage(ModuleType):
self._namespace_prefix = namespace + '.' self._namespace_prefix = namespace + '.'
self._portal_type = portal_type self._portal_type = portal_type
self.__version_suffix_len = len('_version') self.__version_suffix_len = len('_version')
self._lock = threading.RLock() self._load_module_lock = threading.RLock()
self._registry_generate_lock = threading.RLock()
# Add this module to sys.path for future imports # Add this module to sys.path for future imports
sys.modules[namespace] = self sys.modules[namespace] = self
...@@ -109,17 +110,18 @@ class ComponentDynamicPackage(ModuleType): ...@@ -109,17 +110,18 @@ class ComponentDynamicPackage(ModuleType):
# this is only done at startup or upon reset, moreover using the Catalog # this is only done at startup or upon reset, moreover using the Catalog
# is too risky as it lags behind and depends upon objects being # is too risky as it lags behind and depends upon objects being
# reindexed # reindexed
for component in component_tool.objectValues(portal_type=self._portal_type): with self._registry_generate_lock:
# Only consider modified or validated states as state transition will for component in component_tool.objectValues(portal_type=self._portal_type):
# be handled by component_validation_workflow which will take care of # Only consider modified or validated states as state transition will
# updating the registry # be handled by component_validation_workflow which will take care of
if component.getValidationState() in ('modified', 'validated'): # updating the registry
version = component.getVersion(validated_only=True) if component.getValidationState() in ('modified', 'validated'):
# The versions should have always been set on ERP5Site property version = component.getVersion(validated_only=True)
# beforehand # The versions should have always been set on ERP5Site property
if version in version_priority_set: # beforehand
reference = component.getReference(validated_only=True) if version in version_priority_set:
self.__registry_dict.setdefault(reference, {})[version] = component reference = component.getReference(validated_only=True)
self.__registry_dict.setdefault(reference, {})[version] = component
return self.__registry_dict return self.__registry_dict
...@@ -218,7 +220,7 @@ class ComponentDynamicPackage(ModuleType): ...@@ -218,7 +220,7 @@ class ComponentDynamicPackage(ModuleType):
except AttributeError: except AttributeError:
pass pass
else: else:
with self._lock: with self._load_module_lock:
setattr(self._getVersionPackage(version), component_name, module) setattr(self._getVersionPackage(version), component_name, module)
return module return module
...@@ -228,7 +230,7 @@ class ComponentDynamicPackage(ModuleType): ...@@ -228,7 +230,7 @@ class ComponentDynamicPackage(ModuleType):
component_id = '%s.%s_version.%s' % (self._namespace, version, component_id = '%s.%s_version.%s' % (self._namespace, version,
component_name) component_name)
with self._lock: with self._load_module_lock:
new_module = ModuleType(component_id, component.getDescription()) new_module = ModuleType(component_id, component.getDescription())
# The module *must* be in sys.modules before executing the code in case # The module *must* be in sys.modules before executing the code in case
......
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