From: Steve Baker Date: Mon, 10 Dec 2012 03:18:26 +0000 (+1300) Subject: Fix race condition in list_stacks X-Git-Tag: 2014.1~1091^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=60ca97d3918a428a5a852e658e93a8c834fd366c;p=openstack-build%2Fheat-build.git Fix race condition in list_stacks A stack may be deleted between querying the stacks to list and formatting each stack. This issue was found by concurrently creating and deleting 100 stacks while running heat list. Change-Id: I4a47bbdbde111454672c2579caf28b4675c3cf10 --- diff --git a/heat/engine/service.py b/heat/engine/service.py index cf317fca..11efff66 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -15,11 +15,13 @@ import functools import webob +import sqlalchemy.exc from heat.common import context from heat.db import api as db_api from heat.engine import api from heat.engine.event import Event +from heat.common import exception from heat.common import identifier from heat.engine import parser from heat.engine import resources @@ -161,13 +163,21 @@ class EngineService(service.Service): The list_stacks method returns attributes of all stacks. arg1 -> RPC context. """ - stacks = db_api.stack_get_all_by_tenant(context) or [] - def format_stack_detail(s): - stack = parser.Stack.load(context, stack=s, resolve_data=False) - return api.format_stack(stack) + def format_stack_details(stacks): + for s in stacks: + try: + stack = parser.Stack.load(context, stack=s, + resolve_data=False) + except exception.NotFound: + # The stack may have been deleted between listing + # and formatting + pass + else: + yield api.format_stack(stack) - return {'stacks': [format_stack_detail(s) for s in stacks]} + stacks = db_api.stack_get_all_by_tenant(context) or [] + return {'stacks': list(format_stack_details(stacks))} @request_context def create_stack(self, context, stack_name, template, params, args):