Merge "Add retries to avoid dberror for user_creds_delete"
This commit is contained in:
commit
84b38bc9dd
@ -36,6 +36,7 @@ from heat.common.i18n import _
|
|||||||
from heat.db.sqlalchemy import filters as db_filters
|
from heat.db.sqlalchemy import filters as db_filters
|
||||||
from heat.db.sqlalchemy import migration
|
from heat.db.sqlalchemy import migration
|
||||||
from heat.db.sqlalchemy import models
|
from heat.db.sqlalchemy import models
|
||||||
|
from heat.db.sqlalchemy import utils as db_utils
|
||||||
from heat.rpc import api as rpc_api
|
from heat.rpc import api as rpc_api
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -685,6 +686,7 @@ def user_creds_get(user_creds_id):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@db_utils.retry_on_stale_data_error
|
||||||
def user_creds_delete(context, user_creds_id):
|
def user_creds_delete(context, user_creds_id):
|
||||||
creds = model_query(context, models.UserCreds).get(user_creds_id)
|
creds = model_query(context, models.UserCreds).get(user_creds_id)
|
||||||
if not creds:
|
if not creds:
|
||||||
|
@ -215,7 +215,8 @@ class UserCreds(BASE, HeatBase):
|
|||||||
tenant_id = sqlalchemy.Column(sqlalchemy.String(256))
|
tenant_id = sqlalchemy.Column(sqlalchemy.String(256))
|
||||||
trust_id = sqlalchemy.Column(sqlalchemy.String(255))
|
trust_id = sqlalchemy.Column(sqlalchemy.String(255))
|
||||||
trustor_user_id = sqlalchemy.Column(sqlalchemy.String(64))
|
trustor_user_id = sqlalchemy.Column(sqlalchemy.String(64))
|
||||||
stack = relationship(Stack, backref=backref('user_creds'))
|
stack = relationship(Stack, backref=backref('user_creds'),
|
||||||
|
cascade_backrefs=False)
|
||||||
|
|
||||||
|
|
||||||
class Event(BASE, HeatBase):
|
class Event(BASE, HeatBase):
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
# SQLAlchemy helper functions
|
# SQLAlchemy helper functions
|
||||||
|
|
||||||
|
import retrying
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
|
|
||||||
def clone_table(name, parent, meta, newcols=None, ignorecols=None,
|
def clone_table(name, parent, meta, newcols=None, ignorecols=None,
|
||||||
@ -86,3 +88,11 @@ def migrate_data(migrate_engine,
|
|||||||
table.drop()
|
table.drop()
|
||||||
|
|
||||||
new_table.rename(table_name)
|
new_table.rename(table_name)
|
||||||
|
|
||||||
|
|
||||||
|
def retry_on_stale_data_error(func):
|
||||||
|
def is_staledata_error(ex):
|
||||||
|
return isinstance(ex, exc.StaleDataError)
|
||||||
|
wrapper = retrying.retry(stop_max_attempt_number=3,
|
||||||
|
retry_on_exception=is_staledata_error)
|
||||||
|
return wrapper(func)
|
||||||
|
@ -22,6 +22,9 @@ from oslo_config import cfg
|
|||||||
from oslo_db import exception as db_exception
|
from oslo_db import exception as db_exception
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
import six
|
import six
|
||||||
|
from sqlalchemy.orm import exc
|
||||||
|
from sqlalchemy.orm import session
|
||||||
|
|
||||||
|
|
||||||
from heat.common import context
|
from heat.common import context
|
||||||
from heat.common import exception
|
from heat.common import exception
|
||||||
@ -1573,12 +1576,32 @@ class DBAPIUserCredsTest(common.HeatTestCase):
|
|||||||
db_api.user_creds_delete(self.ctx, user_creds['id'])
|
db_api.user_creds_delete(self.ctx, user_creds['id'])
|
||||||
creds = db_api.user_creds_get(user_creds['id'])
|
creds = db_api.user_creds_get(user_creds['id'])
|
||||||
self.assertIsNone(creds)
|
self.assertIsNone(creds)
|
||||||
|
mock_delete = self.patchobject(session.Session, 'delete')
|
||||||
err = self.assertRaises(
|
err = self.assertRaises(
|
||||||
exception.NotFound, db_api.user_creds_delete,
|
exception.NotFound, db_api.user_creds_delete,
|
||||||
self.ctx, user_creds['id'])
|
self.ctx, user_creds['id'])
|
||||||
exp_msg = ('Attempt to delete user creds with id '
|
exp_msg = ('Attempt to delete user creds with id '
|
||||||
'%s that does not exist' % user_creds['id'])
|
'%s that does not exist' % user_creds['id'])
|
||||||
self.assertIn(exp_msg, six.text_type(err))
|
self.assertIn(exp_msg, six.text_type(err))
|
||||||
|
self.assertEqual(0, mock_delete.call_count)
|
||||||
|
|
||||||
|
def test_user_creds_delete_retries(self):
|
||||||
|
mock_delete = self.patchobject(session.Session, 'delete')
|
||||||
|
# returns StaleDataErrors, so we try delete 3 times
|
||||||
|
mock_delete.side_effect = [exc.StaleDataError,
|
||||||
|
exc.StaleDataError,
|
||||||
|
None]
|
||||||
|
user_creds = create_user_creds(self.ctx)
|
||||||
|
self.assertIsNotNone(user_creds['id'])
|
||||||
|
self.assertIsNone(
|
||||||
|
db_api.user_creds_delete(self.ctx, user_creds['id']))
|
||||||
|
self.assertEqual(3, mock_delete.call_count)
|
||||||
|
|
||||||
|
# returns other errors, so we try delete once
|
||||||
|
mock_delete.side_effect = [exc.UnmappedError]
|
||||||
|
self.assertRaises(exc.UnmappedError, db_api.user_creds_delete,
|
||||||
|
self.ctx, user_creds['id'])
|
||||||
|
self.assertEqual(4, mock_delete.call_count)
|
||||||
|
|
||||||
|
|
||||||
class DBAPIStackTagTest(common.HeatTestCase):
|
class DBAPIStackTagTest(common.HeatTestCase):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user