Merge "Mark quota operations as retriable"

This commit is contained in:
Jenkins 2016-09-13 20:34:31 +00:00 committed by Gerrit Code Review
commit 660f3d58d0
4 changed files with 23 additions and 3 deletions

View File

@ -26,6 +26,7 @@ from oslo_db.sqlalchemy import enginefacade
from oslo_log import log as logging
from oslo_utils import excutils
import osprofiler.sqlalchemy
from pecan import util as p_util
import six
import sqlalchemy
from sqlalchemy.orm import exc
@ -137,7 +138,10 @@ def retry_if_session_inactive(context_var_name='context'):
"""
def decorator(f):
try:
ctx_arg_index = f.__code__.co_varnames.index(context_var_name)
# NOTE(kevinbenton): we use pecan's util function here because it
# deals with the horrors of finding args of already decorated
# functions
ctx_arg_index = p_util.getargspec(f).args.index(context_var_name)
except ValueError:
raise RuntimeError(_LE("Could not find position of var %s")
% context_var_name)

View File

@ -40,6 +40,7 @@ class ReservationInfo(collections.namedtuple(
"""Information about a resource reservation."""
@db_api.retry_if_session_inactive()
def get_quota_usage_by_resource_and_tenant(context, resource, tenant_id,
lock_for_update=False):
"""Return usage info for a given resource and tenant.
@ -66,6 +67,7 @@ def get_quota_usage_by_resource_and_tenant(context, resource, tenant_id,
result.dirty)
@db_api.retry_if_session_inactive()
def get_quota_usage_by_resource(context, resource):
query = common_db_api.model_query(context, quota_models.QuotaUsage)
query = query.filter_by(resource=resource)
@ -75,6 +77,7 @@ def get_quota_usage_by_resource(context, resource):
item.dirty) for item in query]
@db_api.retry_if_session_inactive()
def get_quota_usage_by_tenant_id(context, tenant_id):
query = common_db_api.model_query(context, quota_models.QuotaUsage)
query = query.filter_by(tenant_id=tenant_id)
@ -84,6 +87,7 @@ def get_quota_usage_by_tenant_id(context, tenant_id):
item.dirty) for item in query]
@db_api.retry_if_session_inactive()
def set_quota_usage(context, resource, tenant_id,
in_use=None, delta=False):
"""Set resource quota usage.
@ -121,6 +125,7 @@ def set_quota_usage(context, resource, tenant_id,
usage_data.dirty)
@db_api.retry_if_session_inactive()
@db_api.context_manager.writer
def set_quota_usage_dirty(context, resource, tenant_id, dirty=True):
"""Set quota usage dirty bit for a given resource and tenant.
@ -135,6 +140,7 @@ def set_quota_usage_dirty(context, resource, tenant_id, dirty=True):
return query.update({'dirty': dirty})
@db_api.retry_if_session_inactive()
@db_api.context_manager.writer
def set_resources_quota_usage_dirty(context, resources, tenant_id, dirty=True):
"""Set quota usage dirty bit for a given tenant and multiple resources.
@ -153,6 +159,7 @@ def set_resources_quota_usage_dirty(context, resources, tenant_id, dirty=True):
return query.update({'dirty': dirty}, synchronize_session=False)
@db_api.retry_if_session_inactive()
@db_api.context_manager.writer
def set_all_quota_usage_dirty(context, resource, dirty=True):
"""Set the dirty bit on quota usage for all tenants.
@ -166,6 +173,7 @@ def set_all_quota_usage_dirty(context, resource, dirty=True):
return query.update({'dirty': dirty})
@db_api.retry_if_session_inactive()
def create_reservation(context, tenant_id, deltas, expiration=None):
# This method is usually called from within another transaction.
# Consider using begin_nested
@ -186,6 +194,7 @@ def create_reservation(context, tenant_id, deltas, expiration=None):
for delta in resv.resource_deltas))
@db_api.retry_if_session_inactive()
def get_reservation(context, reservation_id):
query = context.session.query(quota_models.Reservation).filter_by(
id=reservation_id)
@ -199,6 +208,7 @@ def get_reservation(context, reservation_id):
for delta in resv.resource_deltas))
@db_api.retry_if_session_inactive()
@db_api.context_manager.writer
def remove_reservation(context, reservation_id, set_dirty=False):
delete_query = context.session.query(quota_models.Reservation).filter_by(
@ -220,6 +230,7 @@ def remove_reservation(context, reservation_id, set_dirty=False):
return num_deleted
@db_api.retry_if_session_inactive()
def get_reservations_for_resources(context, tenant_id, resources,
expired=False):
"""Retrieve total amount of reservations for specified resources.
@ -254,6 +265,7 @@ def get_reservations_for_resources(context, tenant_id, resources,
for (resource, exp, total_reserved) in resv_query)
@db_api.retry_if_session_inactive()
@db_api.context_manager.writer
def remove_expired_reservations(context, tenant_id=None):
now = utcnow()

View File

@ -49,6 +49,7 @@ class DbQuotaDriver(object):
for key, resource in resources.items())
@staticmethod
@db_api.retry_if_session_inactive()
def get_tenant_quotas(context, resources, tenant_id):
"""Given a list of resources, retrieve the quotas for the given
tenant. If no limits are found for the specified tenant, the operation
@ -73,6 +74,7 @@ class DbQuotaDriver(object):
return tenant_quota
@staticmethod
@db_api.retry_if_session_inactive()
def delete_tenant_quota(context, tenant_id):
"""Delete the quota entries for a given tenant_id.
@ -88,6 +90,7 @@ class DbQuotaDriver(object):
raise n_exc.TenantQuotaNotFound(tenant_id=tenant_id)
@staticmethod
@db_api.retry_if_session_inactive()
def get_all_quotas(context, resources):
"""Given a list of resources, retrieve the quotas for the all tenants.
@ -119,6 +122,7 @@ class DbQuotaDriver(object):
return list(all_tenant_quotas.values())
@staticmethod
@db_api.retry_if_session_inactive()
def update_quota_limit(context, tenant_id, resource, limit):
with context.session.begin():
tenant_quota = context.session.query(quota_models.Quota).filter_by(
@ -156,7 +160,7 @@ class DbQuotaDriver(object):
quota_api.remove_expired_reservations(
context, tenant_id=tenant_id)
@db_api.retry_db_errors
@db_api.retry_if_session_inactive()
def make_reservation(self, context, tenant_id, resources, deltas, plugin):
# Lock current reservation table
# NOTE(salv-orlando): This routine uses DB write locks.

View File

@ -207,7 +207,7 @@ class TrackedResource(BaseResource):
# can happen is two or more workers are trying to create a resource of a
# give kind for the same tenant concurrently. Retrying the operation will
# ensure that an UPDATE statement is emitted rather than an INSERT one
@db_api.retry_db_errors
@db_api.retry_if_session_inactive()
def _set_quota_usage(self, context, tenant_id, in_use):
return quota_api.set_quota_usage(
context, self.name, tenant_id, in_use=in_use)