Decorate only Flavor.get_* methods that execute queries

The get_* methods on the Flavor object use a common helper method to
build a query object to execute later.

Currently, the @api_db_api.context_manager.reader decorator which
manages the session is located on the helper method instead of on the
methods that actually execute the database queries. Part of the context
manager's job is to close the session after the query is executed.
Because the decorator is not on the methods that actually execute the
queries, those database connections are not being closed and it will
eventually lead to errors like:

  sqlalchemy.exc.TimeoutError: QueuePool limit of size 5 overflow 50
  reached, connection timed out, timeout 30.00 (Background on this
  error at: https://sqlalche.me/e/14/3o7r)

which means the connection pool size plus the overflow size has been
reached and the pool will block for a fixed period of time before
timing out and raising this error.

This removes the @api_db_api.context_manager.reader decorator from the
query build helper method and adds it to the Flavor.get_* methods that
execute the database queries.

Closes-Bug: #2027755

Change-Id: I4bf83d1642b62ab103716aff6dae7438646e2b31
This commit is contained in:
melanie witt 2023-07-14 02:23:23 +00:00
parent f7ce4df51c
commit 9ae6240c92
1 changed files with 5 additions and 1 deletions

View File

@ -270,8 +270,9 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
return flavor
@staticmethod
@api_db_api.context_manager.reader
def _flavor_get_query_from_db(context):
# We don't use a database context decorator on this method because this
# method is not executing a query, it's only building one.
query = context.session.query(api_models.Flavors).options(
orm.joinedload(api_models.Flavors.extra_specs)
)
@ -285,6 +286,7 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
@staticmethod
@db_utils.require_context
@api_db_api.context_manager.reader
def _flavor_get_from_db(context, id):
"""Returns a dict describing specific flavor."""
result = Flavor._flavor_get_query_from_db(context).\
@ -296,6 +298,7 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
@staticmethod
@db_utils.require_context
@api_db_api.context_manager.reader
def _flavor_get_by_name_from_db(context, name):
"""Returns a dict describing specific flavor."""
result = Flavor._flavor_get_query_from_db(context).\
@ -307,6 +310,7 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
@staticmethod
@db_utils.require_context
@api_db_api.context_manager.reader
def _flavor_get_by_flavor_id_from_db(context, flavor_id):
"""Returns a dict describing specific flavor_id."""
result = Flavor._flavor_get_query_from_db(context).\