From 9ae6240c92e212b2fa96d5163f68ef1b30ee03b7 Mon Sep 17 00:00:00 2001 From: melanie witt Date: Fri, 14 Jul 2023 02:23:23 +0000 Subject: [PATCH] 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 --- nova/objects/flavor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nova/objects/flavor.py b/nova/objects/flavor.py index 01eeb62331e0..6d10b98559d2 100644 --- a/nova/objects/flavor.py +++ b/nova/objects/flavor.py @@ -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).\