From e661706d1304d1d6304415eaea370a1f31e29a8c Mon Sep 17 00:00:00 2001 From: Fatih Acar Date: Wed, 16 Apr 2025 00:12:47 +0200 Subject: [PATCH 1/3] fix(backend): make sure constraint runner uses correct db session Signed-off-by: Fatih Acar --- backend/infrahub/core/constraint/node/runner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/infrahub/core/constraint/node/runner.py b/backend/infrahub/core/constraint/node/runner.py index 3a256347bb..26fba9fbf8 100644 --- a/backend/infrahub/core/constraint/node/runner.py +++ b/backend/infrahub/core/constraint/node/runner.py @@ -30,6 +30,7 @@ async def check( await node.resolve_relationships(db=db) if not skip_uniqueness_check: + self.uniqueness_constraint.db = db await self.uniqueness_constraint.check(node, filters=field_filters) for relationship_name in node.get_schema().relationship_names: @@ -38,4 +39,5 @@ async def check( relationship_manager: RelationshipManager = getattr(node, relationship_name) await relationship_manager.fetch_relationship_ids(db=db, force_refresh=True) for relationship_constraint in self.relationship_manager_constraints: + relationship_constraint.db = db await relationship_constraint.check(relm=relationship_manager, node_schema=node.get_schema()) From 76d6aabed032fa653a4219086b4ca822cc90958b Mon Sep 17 00:00:00 2001 From: Fatih Acar Date: Wed, 16 Apr 2025 00:13:50 +0200 Subject: [PATCH 2/3] fix(backend): do not start new session within a transaction for the constraint runner Signed-off-by: Fatih Acar --- .../infrahub/core/constraint/node/runner.py | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/backend/infrahub/core/constraint/node/runner.py b/backend/infrahub/core/constraint/node/runner.py index 26fba9fbf8..576f78aa3d 100644 --- a/backend/infrahub/core/constraint/node/runner.py +++ b/backend/infrahub/core/constraint/node/runner.py @@ -23,21 +23,37 @@ def __init__( self.uniqueness_constraint = uniqueness_constraint self.relationship_manager_constraints = relationship_manager_constraints + async def _check( + self, + db: InfrahubDatabase, + node: Node, + field_filters: list[str] | None = None, + skip_uniqueness_check: bool = False, + ) -> None: + await node.resolve_relationships(db=db) + + if not skip_uniqueness_check: + self.uniqueness_constraint.db = db + await self.uniqueness_constraint.check(node, filters=field_filters) + + for relationship_name in node.get_schema().relationship_names: + if field_filters and relationship_name not in field_filters: + continue + relationship_manager: RelationshipManager = getattr(node, relationship_name) + await relationship_manager.fetch_relationship_ids(db=db, force_refresh=True) + for relationship_constraint in self.relationship_manager_constraints: + relationship_constraint.db = db + await relationship_constraint.check(relm=relationship_manager, node_schema=node.get_schema()) + async def check( self, node: Node, field_filters: list[str] | None = None, skip_uniqueness_check: bool = False ) -> None: - async with self.db.start_session() as db: - await node.resolve_relationships(db=db) - - if not skip_uniqueness_check: - self.uniqueness_constraint.db = db - await self.uniqueness_constraint.check(node, filters=field_filters) - - for relationship_name in node.get_schema().relationship_names: - if field_filters and relationship_name not in field_filters: - continue - relationship_manager: RelationshipManager = getattr(node, relationship_name) - await relationship_manager.fetch_relationship_ids(db=db, force_refresh=True) - for relationship_constraint in self.relationship_manager_constraints: - relationship_constraint.db = db - await relationship_constraint.check(relm=relationship_manager, node_schema=node.get_schema()) + if not self.db.is_transaction: + async with self.db.start_session(read_only=False) as db: + await self._check( + db=db, node=node, field_filters=field_filters, skip_uniqueness_check=skip_uniqueness_check + ) + else: + await self._check( + db=self.db, node=node, field_filters=field_filters, skip_uniqueness_check=skip_uniqueness_check + ) From dab869417d5eeafaa760d6efeb695ca78f8680d6 Mon Sep 17 00:00:00 2001 From: Fatih Acar Date: Wed, 16 Apr 2025 00:16:02 +0200 Subject: [PATCH 3/3] fix(backend): never reuse session when starting a transaction Signed-off-by: Fatih Acar --- backend/infrahub/database/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/infrahub/database/__init__.py b/backend/infrahub/database/__init__.py index 3661f933ca..dc90fa1239 100644 --- a/backend/infrahub/database/__init__.py +++ b/backend/infrahub/database/__init__.py @@ -245,7 +245,6 @@ def start_transaction(self, schemas: list[SchemaBranch] | None = None) -> Infrah schemas=schemas or self._schemas.values(), db_manager=self.manager, driver=self._driver, - session=self._session, session_mode=self._session_mode, queries_names_to_config=self.queries_names_to_config, **context,