Skip to content

Commit

Permalink
Merge pull request #316 from ynput/database-connection-optimizations
Browse files Browse the repository at this point in the history
Database connection optimizations
  • Loading branch information
martastain authored Aug 13, 2024
2 parents 24fae3f + fd6f616 commit 5c3eb15
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 15 deletions.
14 changes: 13 additions & 1 deletion ayon_server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ class AyonConfig(BaseModel):
example="postgres://user:[email protected]:5432/ayon",
)

postgres_pool_size: int = Field(
64,
description="Postgres connection pool size",
example=64,
)

postgres_pool_timeout: int = Field(
20,
description="Postgres connection pool timeout",
example=20,
)

session_ttl: int = Field(
default=24 * 3600,
description="Session lifetime in seconds",
Expand Down Expand Up @@ -172,7 +184,7 @@ class AyonConfig(BaseModel):

http_timeout: int = Field(
default=120,
description="Timeout for HTTP requests the server uses "
description="The default timeout for HTTP requests the server uses "
"to connect to external services",
)

Expand Down
2 changes: 1 addition & 1 deletion ayon_server/helpers/deploy_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ async def create_project_from_anatomy(
await assign_default_users_to_project(project.name, conn)

end_time = time.monotonic()
logging.info(f"Deployed project {project.name} in {end_time - start_time:.2f}s")
logging.debug(f"Deployed project {project.name} in {end_time - start_time:.2f}s")

await dispatch_event(
"entity.project.created",
Expand Down
12 changes: 3 additions & 9 deletions ayon_server/lib/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class Postgres:
Provides an interface for interacting with a Postgres database.
"""

default_acquire_timeout: int = 10
shutting_down: bool = False
pool: asyncpg.pool.Pool | None = None # type: ignore

Expand All @@ -42,7 +41,7 @@ async def acquire(
raise ConnectionError("Connection pool is not initialized.")

if timeout is None:
timeout = cls.default_acquire_timeout
timeout = ayonconfig.postgres_pool_timeout

try:
connection_proxy = await cls.pool.acquire(timeout=timeout)
Expand Down Expand Up @@ -82,20 +81,15 @@ def get_available_connections(cls) -> int:

@classmethod
async def connect(cls) -> None:
"""Create a PostgreSQL connection pool.
By default, we use 24 as max_size, since default maximum
connection value of postgres is 100 so, 25 is perfect for
4 workers and a small reserve.
"""
"""Create a PostgreSQL connection pool."""

if cls.shutting_down:
print("Unable to connect to Postgres while shutting down.")
return
cls.pool = await asyncpg.create_pool(
ayonconfig.postgres_url,
min_size=10,
max_size=24,
max_size=ayonconfig.postgres_pool_size,
max_inactive_connection_lifetime=20,
init=cls.init_connection,
)
Expand Down
20 changes: 16 additions & 4 deletions ayon_server/metrics/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class SystemMetricsData(OPModel):
runtime_seconds: float = Field(0, title="Runtime", example=123456)
db_size_shared: int = Field(0, title="Shared database size", example=123456)
db_size_total: int = Field(0, title="Total database size", example=123456)
db_available_connections: int = Field(
0,
title="Available database connections",
example=123456,
)
redis_size_total: int = Field(0, title="Total redis size", example=123456)
storage_utilization_total: int = Field(
0,
Expand All @@ -50,7 +55,7 @@ def __init__(self):
self.boot_time = psutil.boot_time()
self.run_time = time.time()

@aiocache.cached(ttl=60)
@aiocache.cached(ttl=120)
async def get_db_sizes(self) -> list[Metric]:
result = []
query = """
Expand Down Expand Up @@ -100,14 +105,21 @@ async def render_prometheus(self) -> str:
for metric in await self.status():
result += metric.render_prometheus()

for metric in await self.get_db_sizes():
for metric in await self.get_upload_sizes():
result += metric.render_prometheus()

for metric in await self.get_upload_sizes():
for metric in await self.get_db_sizes():
result += metric.render_prometheus()

# ~realtime data
db_avail = Metric(
"db_available_connections", Postgres.get_available_connections()
)
result += db_avail.render_prometheus()

return result

@aiocache.cached(ttl=60)
@aiocache.cached(ttl=120)
async def get_upload_sizes(self) -> list[Metric]:
result: list[Metric] = []

Expand Down

0 comments on commit 5c3eb15

Please sign in to comment.