Skip to content

Commit

Permalink
timeout the connection & initialization of the db
Browse files Browse the repository at this point in the history
  • Loading branch information
juanmirocks committed Jul 11, 2023
1 parent 68fcdf5 commit 8f1111d
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
2 changes: 1 addition & 1 deletion fastchecks/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,6 @@ async def main(args: NamedArgs) -> None:

try:
asyncio.run(main(args))
except (KeyboardInterrupt, SystemExit):
except (KeyboardInterrupt):
# ignore program-exit-like exceptions in the cli
pass
17 changes: 13 additions & 4 deletions fastchecks/runner.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
import logging
import sys
from typing import AsyncIterator

import aiohttp
Expand Down Expand Up @@ -51,7 +52,7 @@ def __init__(
# -----------------------------------------------------------------------------

@classmethod
async def with_single_datastore_postgres(cls, pg_conninfo: str, auto_init: bool, **kwargs) -> "ChecksRunnerContext":
async def with_single_datastore_postgres(cls, pg_conninfo: str, auto_init: bool, timeout_init_sec: float = 10, **kwargs) -> "ChecksRunnerContext":
vutil.validated_pg_conninfo(pg_conninfo)

ctx = cls(
Expand All @@ -63,19 +64,27 @@ async def with_single_datastore_postgres(cls, pg_conninfo: str, auto_init: bool,

try:
# For instance, we use the socket's pool to check if the single common datastore is ready
is_ready = await common_single_pg_datastore_is_ready(ctx.checks._pool)
is_ready = await common_single_pg_datastore_is_ready(ctx.checks._pool, timeout=timeout_init_sec)
logging.info(f"Postgres datastore is ready: {is_ready}")

if not is_ready:
require(
auto_init,
"The postgres database is not initialized and auto_init==False (set to True to auto-init, i.e., create the db schema)",
)
inited = await common_single_pg_datastore_init(ctx.checks._pool)

inited = False



async with asyncio.timeout(delay=timeout_init_sec):
inited = await common_single_pg_datastore_init(ctx.checks._pool, timeout=timeout_init_sec)

require(inited, "The postgres database could not be initialized")
except:
logging.critical("Could not initialize the postgres database", exc_info=True)
logging.critical(f"Could not initialize the postgres database after {timeout_init_sec}s -- does the DB exist?", exc_info=False)
await ctx.close()
sys.exit(2)

return ctx

Expand Down
8 changes: 4 additions & 4 deletions fastchecks/sockets/postgres/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from fastchecks.types import CheckResult, WebsiteCheck, WebsiteCheckScheduled


async def common_single_pg_datastore_is_ready(pool: AsyncConnectionPool) -> bool:
async with pool.connection() as aconn:
async def common_single_pg_datastore_is_ready(pool: AsyncConnectionPool, timeout: float) -> bool:
async with pool.connection(timeout=timeout) as aconn:
# We just test the WebsiteCheck (written in lowercase) for existence.
# Note: not 100% reliable (as no other objects are tested) but good enough for now.
# MAYBE: support versioning of schemas with a hidden Version/Evolutions table or similar.
Expand All @@ -31,9 +31,9 @@ async def common_single_pg_datastore_is_ready(pool: AsyncConnectionPool) -> bool
return cur.rowcount == 1


async def common_single_pg_datastore_init(pool: AsyncConnectionPool) -> bool:
async def common_single_pg_datastore_init(pool: AsyncConnectionPool, timeout: float) -> bool:
# WARNING: Assumed to not be initialized
async with pool.connection() as aconn:
async with pool.connection(timeout=timeout) as aconn:
init_sql = resources.files(schema).joinpath("up.sql").read_text()
await aconn.execute(init_sql)
return True
Expand Down
2 changes: 1 addition & 1 deletion tests/test_runner_with_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async def setup_module():
print(conn.execute(query_safe).statusmessage)

CTX = await ChecksRunnerContext.with_single_datastore_postgres(
TEST_CONNINFO, default_interval_seconds=1, auto_init=True
TEST_CONNINFO, default_interval_seconds=1, auto_init=True, timeout_init_sec=5
)

yield "initialized"
Expand Down

0 comments on commit 8f1111d

Please sign in to comment.