Skip to content

Commit daf88b4

Browse files
authored
Merge pull request #4504 from opsmill/lgu-perf-benchmarks
Instantiate DB queries benchmarking framework
2 parents 239b3ba + 09007ff commit daf88b4

29 files changed

+800
-786
lines changed

backend/infrahub/core/query/__init__.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from infrahub import config
1515
from infrahub.core.constants import PermissionLevel
1616
from infrahub.core.timestamp import Timestamp
17-
from infrahub.database.constants import DatabaseType, Neo4jRuntime
1817
from infrahub.exceptions import QueryError
1918

2019
if TYPE_CHECKING:
@@ -24,6 +23,7 @@
2423
from infrahub.core.branch import Branch
2524
from infrahub.database import InfrahubDatabase
2625

26+
2727
RETURN_TYPE = TypeVar("RETURN_TYPE")
2828

2929

@@ -518,9 +518,7 @@ def _get_params_for_neo4j_shell(self) -> str:
518518

519519
return ":params { " + ", ".join(params) + " }"
520520

521-
async def execute(
522-
self, db: InfrahubDatabase, profile: bool = False, runtime: Neo4jRuntime = Neo4jRuntime.DEFAULT
523-
) -> Self:
521+
async def execute(self, db: InfrahubDatabase) -> Self:
524522
# Ensure all mandatory params have been provided
525523
# Ensure at least 1 return obj has been defined
526524

@@ -529,12 +527,6 @@ async def execute(
529527

530528
query_str = self.get_query()
531529

532-
if profile:
533-
query_str = "PROFILE\n" + query_str
534-
535-
if runtime != Neo4jRuntime.DEFAULT and db.db_type == DatabaseType.NEO4J:
536-
query_str = f"CYPHER runtime={runtime.value}\n" + query_str
537-
538530
if self.type == QueryType.READ:
539531
if self.limit or self.offset:
540532
results = await db.execute_query(query=query_str, params=self.params, name=self.name)

backend/infrahub/database/__init__.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import asyncio
44
import random
5+
from dataclasses import dataclass
56
from typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, TypeVar, Union
67

78
from neo4j import (
@@ -30,7 +31,7 @@
3031
from infrahub.log import get_logger
3132
from infrahub.utils import InfrahubStringEnum
3233

33-
from .constants import DatabaseType
34+
from .constants import DatabaseType, Neo4jRuntime
3435
from .memgraph import DatabaseManagerMemgraph
3536
from .metrics import QUERY_EXECUTION_METRICS, TRANSACTION_RETRIES
3637
from .neo4j import DatabaseManagerNeo4j
@@ -50,6 +51,12 @@
5051
log = get_logger()
5152

5253

54+
@dataclass
55+
class QueryConfig:
56+
neo4j_runtime: Neo4jRuntime = Neo4jRuntime.DEFAULT
57+
profile_memory: bool = False
58+
59+
5360
class InfrahubDatabaseMode(InfrahubStringEnum):
5461
DRIVER = "driver"
5562
SESSION = "session"
@@ -134,13 +141,15 @@ def __init__(
134141
session: Optional[AsyncSession] = None,
135142
session_mode: InfrahubDatabaseSessionMode = InfrahubDatabaseSessionMode.WRITE,
136143
transaction: Optional[AsyncTransaction] = None,
137-
) -> None:
144+
queries_names_to_config: Optional[dict[str, QueryConfig]] = None,
145+
):
138146
self._mode: InfrahubDatabaseMode = mode
139147
self._driver: AsyncDriver = driver
140148
self._session: Optional[AsyncSession] = session
141149
self._session_mode: InfrahubDatabaseSessionMode = session_mode
142150
self._is_session_local: bool = False
143151
self._transaction: Optional[AsyncTransaction] = transaction
152+
self.queries_names_to_config = queries_names_to_config if queries_names_to_config is not None else {}
144153

145154
if schemas:
146155
self._schemas: dict[str, SchemaBranch] = {schema.name: schema for schema in schemas}
@@ -189,6 +198,7 @@ def start_session(self, read_only: bool = False, schemas: Optional[list[SchemaBr
189198
db_manager=self.manager,
190199
driver=self._driver,
191200
session_mode=session_mode,
201+
queries_names_to_config=self.queries_names_to_config,
192202
)
193203

194204
def start_transaction(self, schemas: Optional[list[SchemaBranch]] = None) -> InfrahubDatabase:
@@ -200,6 +210,7 @@ def start_transaction(self, schemas: Optional[list[SchemaBranch]] = None) -> Inf
200210
driver=self._driver,
201211
session=self._session,
202212
session_mode=self._session_mode,
213+
queries_names_to_config=self.queries_names_to_config,
203214
)
204215

205216
async def session(self) -> AsyncSession:
@@ -274,14 +285,8 @@ async def close(self) -> None:
274285
async def execute_query(
275286
self, query: str, params: Optional[dict[str, Any]] = None, name: Optional[str] = "undefined"
276287
) -> list[Record]:
277-
with trace.get_tracer(__name__).start_as_current_span("execute_db_query") as span:
278-
span.set_attribute("query", query)
279-
if name:
280-
span.set_attribute("query_name", name)
281-
282-
with QUERY_EXECUTION_METRICS.labels(self._session_mode.value, name).time():
283-
response = await self.run_query(query=query, params=params)
284-
return [item async for item in response]
288+
results, _ = await self.execute_query_with_metadata(query=query, params=params, name=name)
289+
return results
285290

286291
async def execute_query_with_metadata(
287292
self, query: str, params: Optional[dict[str, Any]] = None, name: Optional[str] = "undefined"
@@ -291,6 +296,17 @@ async def execute_query_with_metadata(
291296
if name:
292297
span.set_attribute("query_name", name)
293298

299+
try:
300+
query_config = self.queries_names_to_config[name]
301+
if self.db_type == DatabaseType.NEO4J:
302+
runtime = self.queries_names_to_config[name].neo4j_runtime
303+
if runtime != Neo4jRuntime.DEFAULT:
304+
query = f"CYPHER runtime = {runtime.value}\n" + query
305+
if query_config.profile_memory:
306+
query = "PROFILE\n" + query
307+
except KeyError:
308+
pass # No specific config for this query
309+
294310
with QUERY_EXECUTION_METRICS.labels(self._session_mode.value, name).time():
295311
response = await self.run_query(query=query, params=params, name=name)
296312
results = [item async for item in response]

backend/infrahub/database/analyzer.py

Lines changed: 0 additions & 206 deletions
This file was deleted.

backend/infrahub/database/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Neo4jRuntime(str, Enum):
1111
INTERPRETED = "interpreted"
1212
SLOTTED = "slotted"
1313
PIPELINED = "pipelined"
14+
PARALLEL = "parallel"
1415

1516

1617
class IndexType(str, Enum):

0 commit comments

Comments
 (0)