584571c3d8
Garbage collection is triggered by io.murano.system.GC.collect() static method. Garbage collector destroys all object that are not reachable anymore. GC can handle objects with cross-references and isolated object graphs. When portion of object model becomes not reachable it destroyed in predictable order such that child objects get destroyed before their parents and, when possible, before objects that are subscribed to their destruction notifications. Internally, both pre-deployment garbage collection (that was done by comparision of ``Objects`` and ``ObjectsCopy``) and post-deployment orphan object collection are now done through the new GC. MuranoPL GC utilizes Python GC to track and collect objects. The main idea is to make ObjectStore have weak links only and prevent hard links in other dsl places so that only links between objects remain. Then prevent Python GC to automatically delete objects that are not used anymore and use gc.collect() to obtain a list of objects that are both not reachable and cannot be destroyed and then destroy them in the correct order. Targets-blueprint: dependency-driven-resource-deallocation Closes-Bug: #1619635 Closes-Bug: #1597747 Change-Id: I653d8f71f003afa0a1ea588c9d14198571f5ad14
257 lines
7.3 KiB
Python
257 lines
7.3 KiB
Python
# Copyright (c) 2016 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import semantic_version
|
|
from yaql.language import specs
|
|
from yaql import yaqlization
|
|
|
|
from murano.dsl import dsl
|
|
from murano.dsl import dsl_types
|
|
from murano.dsl import helpers
|
|
from murano.dsl import meta
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoType)
|
|
@specs.name('name')
|
|
def type_name(murano_type):
|
|
return murano_type.name
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoType)
|
|
@specs.name('usage')
|
|
def type_usage(murano_type):
|
|
return murano_type.usage
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoClass)
|
|
def methods(murano_class):
|
|
all_method_names = murano_class.all_method_names
|
|
return tuple(
|
|
murano_method
|
|
for name in all_method_names
|
|
if not name.startswith('__') and not name.startswith('.')
|
|
for murano_method in murano_class.find_method(name)
|
|
)
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoClass)
|
|
def properties(murano_class):
|
|
all_property_names = murano_class.all_property_names
|
|
return tuple(
|
|
prop
|
|
for prop_name in all_property_names
|
|
if not prop_name.startswith('__') and not prop_name.startswith('.')
|
|
for prop in murano_class.find_property(prop_name)
|
|
)
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoClass)
|
|
def ancestors(murano_class):
|
|
return tuple(murano_class.ancestors())
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoType)
|
|
def package(murano_type):
|
|
return murano_type.package
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoClass)
|
|
@specs.name('version')
|
|
def type_version(murano_type):
|
|
return murano_type.version
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoProperty)
|
|
@specs.name('name')
|
|
def property_name(murano_property):
|
|
return murano_property.name
|
|
|
|
|
|
# TODO(ativelkov): add 'default' to return some wrapped YAQL expression
|
|
# @specs.yaql_property(dsl_types.MuranoProperty)
|
|
# @specs.name('default')
|
|
# def property_default(murano_property):
|
|
# return murano_property.default
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoProperty)
|
|
@specs.name('has_default')
|
|
def property_has_default(murano_property):
|
|
return murano_property.has_default
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoProperty)
|
|
@specs.name('usage')
|
|
def property_usage(murano_property):
|
|
return murano_property.usage
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoProperty)
|
|
@specs.name('declaring_type')
|
|
def property_owner(murano_property):
|
|
return murano_property.declaring_type
|
|
|
|
|
|
@specs.name('get_value')
|
|
@specs.parameter('property_', dsl_types.MuranoProperty)
|
|
@specs.parameter('object_', dsl.MuranoObjectParameter(
|
|
nullable=True, decorate=False))
|
|
@specs.method
|
|
def property_get_value(context, property_, object_):
|
|
if object_ is None:
|
|
return helpers.get_executor().get_static_property(
|
|
property_.declaring_type, name=property_.name, context=context)
|
|
return object_.cast(property_.declaring_type).get_property(
|
|
name=property_.name, context=context)
|
|
|
|
|
|
@specs.name('set_value')
|
|
@specs.parameter('property_', dsl_types.MuranoProperty)
|
|
@specs.parameter('object_', dsl.MuranoObjectParameter(
|
|
nullable=True, decorate=False))
|
|
@specs.method
|
|
def property_set_value(context, property_, object_, value):
|
|
if object_ is None:
|
|
helpers.get_executor().set_static_property(
|
|
property_.declaring_type,
|
|
name=property_.name, value=value, context=context)
|
|
else:
|
|
object_.cast(property_.declaring_type).set_property(
|
|
name=property_.name, value=value, context=context)
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethod)
|
|
@specs.name('name')
|
|
def method_name(murano_method):
|
|
return murano_method.name
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethod)
|
|
def arguments(murano_method):
|
|
if murano_method.arguments_scheme is None:
|
|
return None
|
|
return tuple(murano_method.arguments_scheme.values())
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethod)
|
|
@specs.name('declaring_type')
|
|
def method_owner(murano_method):
|
|
return murano_method.declaring_type
|
|
|
|
|
|
@specs.parameter('method', dsl_types.MuranoMethod)
|
|
@specs.parameter('__object', dsl.MuranoObjectParameter(nullable=True))
|
|
@specs.name('invoke')
|
|
@specs.method
|
|
def method_invoke(context, method, __object, *args, **kwargs):
|
|
return method.invoke(__object, args, kwargs, context)
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoPackage)
|
|
def types(murano_package):
|
|
return tuple(
|
|
murano_package.find_class(cls, False)
|
|
for cls in murano_package.classes
|
|
)
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoPackage)
|
|
@specs.name('name')
|
|
def package_name(murano_package):
|
|
return murano_package.name
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoPackage)
|
|
@specs.name('version')
|
|
def package_version(murano_package):
|
|
return murano_package.version
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethodArgument)
|
|
@specs.name('name')
|
|
def argument_name(method_argument):
|
|
return method_argument.name
|
|
|
|
# TODO(ativelkov): add 'default' to return some wrapped YAQL expression
|
|
# @specs.yaql_property(dsl_types.MuranoMethodArgument)
|
|
# @specs.name('default')
|
|
# def argument_default(method_argument):
|
|
# return method_argument.default
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethodArgument)
|
|
@specs.name('has_default')
|
|
def argument_has_default(method_argument):
|
|
return method_argument.has_default
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethodArgument)
|
|
@specs.name('usage')
|
|
def argument_usage(method_argument):
|
|
return method_argument.usage
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMethodArgument)
|
|
@specs.name('declaring_method')
|
|
def argument_owner(method_argument):
|
|
return method_argument.murano_method
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoType)
|
|
@specs.name('type')
|
|
def type_to_type_ref(murano_type):
|
|
return murano_type.get_reference()
|
|
|
|
|
|
@specs.parameter('provider', meta.MetaProvider)
|
|
@specs.name('#property#meta')
|
|
def get_meta(context, provider):
|
|
return provider.get_meta(context)
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMetaClass)
|
|
def cardinality(murano_meta_class):
|
|
return murano_meta_class.cardinality
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMetaClass)
|
|
def targets(murano_meta_class):
|
|
return murano_meta_class.targets
|
|
|
|
|
|
@specs.yaql_property(dsl_types.MuranoMetaClass)
|
|
def inherited(murano_meta_class):
|
|
return murano_meta_class.inherited
|
|
|
|
|
|
def register(context):
|
|
funcs = (
|
|
type_name, type_usage, type_version, type_to_type_ref,
|
|
methods, properties, ancestors, package,
|
|
property_name, property_has_default, property_owner,
|
|
property_usage, property_get_value, property_set_value,
|
|
method_name, arguments, method_owner, method_invoke,
|
|
types, package_name, package_version,
|
|
argument_name, argument_has_default, argument_owner,
|
|
argument_usage,
|
|
cardinality, targets, inherited,
|
|
get_meta
|
|
)
|
|
for f in funcs:
|
|
context.register_function(f)
|
|
|
|
yaqlization.yaqlize(semantic_version.Version, whitelist=[
|
|
'major', 'minor', 'patch', 'prerelease', 'build'
|
|
])
|