Merge "Avoid creating two Stacks when loading Resource"

This commit is contained in:
Jenkins 2017-08-14 12:23:17 +00:00 committed by Gerrit Code Review
commit b4a1ad2bd5
3 changed files with 30 additions and 24 deletions

View File

@ -45,10 +45,10 @@ from heat.engine import scheduler
from heat.engine import status from heat.engine import status
from heat.engine import support from heat.engine import support
from heat.engine import sync_point from heat.engine import sync_point
from heat.engine import template
from heat.objects import resource as resource_objects from heat.objects import resource as resource_objects
from heat.objects import resource_data as resource_data_objects from heat.objects import resource_data as resource_data_objects
from heat.objects import resource_properties_data as rpd_objects from heat.objects import resource_properties_data as rpd_objects
from heat.objects import stack as stack_objects
from heat.rpc import client as rpc_client from heat.rpc import client as rpc_client
cfg.CONF.import_opt('action_retry_limit', 'heat.common.config') cfg.CONF.import_opt('action_retry_limit', 'heat.common.config')
@ -320,36 +320,45 @@ class Resource(status.ResourceStatus):
@classmethod @classmethod
def load(cls, context, resource_id, current_traversal, is_update, data): def load(cls, context, resource_id, current_traversal, is_update, data):
"""Load a specified resource from the database to check.
Returns a tuple of the Resource, the StackDefinition corresponding to
the resource's ResourceDefinition (i.e. the one the resource was last
updated to if it has already been created, or the one it will be
created with if it hasn't been already), and the Stack containing the
latest StackDefinition (i.e. the one that the latest traversal is
updating to.
The latter two must remain in-scope, because the Resource holds weak
references to them.
"""
from heat.engine import stack as stack_mod from heat.engine import stack as stack_mod
db_res = resource_objects.Resource.get_obj(context, resource_id) db_res = resource_objects.Resource.get_obj(context, resource_id)
curr_stack = stack_mod.Stack.load(context, stack_id=db_res.stack_id, curr_stack = stack_mod.Stack.load(context, stack_id=db_res.stack_id,
cache_data=data) cache_data=data)
resource_owning_stack = curr_stack initial_stk_defn = latest_stk_defn = curr_stack.defn
if (db_res.current_template_id != curr_stack.t.id and if (db_res.current_template_id != curr_stack.t.id and
(db_res.action != cls.INIT or (db_res.action != cls.INIT or
not is_update or not is_update or
current_traversal != curr_stack.current_traversal)): current_traversal != curr_stack.current_traversal)):
# load stack with template owning the resource # load the definition associated with the resource's template
db_stack = stack_objects.Stack.get_by_id(context, db_res.stack_id) current_template_id = db_res.current_template_id
db_stack.raw_template = None current_template = template.Template.load(context,
db_stack.raw_template_id = db_res.current_template_id current_template_id)
resource_owning_stack = stack_mod.Stack.load(context, initial_stk_defn = curr_stack.defn.clone_with_new_template(
stack=db_stack) current_template,
curr_stack.identifier())
curr_stack.defn = initial_stk_defn
# Load only the resource in question; don't load all resources # Load only the resource in question; don't load all resources
# by invoking stack.resources. Maintain light-weight stack. # by invoking stack.resources. Maintain light-weight stack.
res_defn = resource_owning_stack.defn.resource_definition(db_res.name) res_defn = initial_stk_defn.resource_definition(db_res.name)
resource = cls(db_res.name, res_defn, resource_owning_stack) resource = cls(db_res.name, res_defn, curr_stack)
resource._load_data(db_res) resource._load_data(db_res)
# assign current stack to the resource for updates curr_stack.defn = latest_stk_defn
if is_update: return resource, initial_stk_defn, curr_stack
resource.stack = curr_stack
# return resource owning stack so that it is not GCed since it
# is the only stack instance with a weak-ref from resource
return resource, resource_owning_stack, curr_stack
def make_replacement(self, new_tmpl_id): def make_replacement(self, new_tmpl_id):
# 1. create the replacement with "replaces" = self.id # 1. create the replacement with "replaces" = self.id

View File

@ -94,11 +94,6 @@ class WaitCondition(heat_wc.HeatWaitCondition):
raise ValueError(_("WaitCondition invalid Handle %s") % raise ValueError(_("WaitCondition invalid Handle %s") %
handle_id.resource_name) handle_id.resource_name)
def _get_handle_resource(self):
handle_url = self.properties[self.HANDLE]
handle_id = identifier.ResourceIdentifier.from_arn_url(handle_url)
return self.stack[handle_id.resource_name]
def handle_create(self): def handle_create(self):
self._validate_handle_url() self._validate_handle_url()
return super(WaitCondition, self).handle_create() return super(WaitCondition, self).handle_create()

View File

@ -170,8 +170,10 @@ class WorkerService(object):
in_data = sync_point.deserialize_input_data(data) in_data = sync_point.deserialize_input_data(data)
resource_data = node_data.load_resources_data(in_data if is_update resource_data = node_data.load_resources_data(in_data if is_update
else {}) else {})
rsrc, rsrc_owning_stack, stack = check_resource.load_resource( rsrc, stk_defn, stack = check_resource.load_resource(cnxt, resource_id,
cnxt, resource_id, resource_data, current_traversal, is_update) resource_data,
current_traversal,
is_update)
if rsrc is None: if rsrc is None:
return return