From a72c8d9db4558b9c9144b0e7307b9a8702913cf4 Mon Sep 17 00:00:00 2001 From: Fantix King Date: Wed, 23 Oct 2024 14:05:09 -0400 Subject: [PATCH] ext: fix issues in net gc task (#7904) * don't run on dropping databases * don't call asyncio.wait([]) * fix wrong logging without decoding JSON --- edb/server/net_worker.py | 16 ++++++++++----- edb/server/protocol/auth_ext/pkce.py | 30 +++++++++++++++++----------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/edb/server/net_worker.py b/edb/server/net_worker.py index 33cd658d0a6..4267689836d 100644 --- a/edb/server/net_worker.py +++ b/edb/server/net_worker.py @@ -265,7 +265,11 @@ def _warn(e): ) async for iteration in rloop: async with iteration: - result = await execute.parse_execute_json( + if not db.tenant.is_database_connectable(db.name): + # Don't run the net_worker if the database is not + # connectable, e.g. being dropped + continue + result_json = await execute.parse_execute_json( db, """ with requests := ( @@ -274,14 +278,15 @@ def _warn(e): and (datetime_of_statement() - .updated_at) > $expires_in ) - delete requests; + select count((delete requests)); """, variables={"expires_in": expires_in.to_backend_str()}, cached_globally=True, tx_isolation=defines.TxIsolationLevel.RepeatableRead, ) - if len(result) > 0: - logger.info(f"Deleted requests: {result!r}") + result: list[int] = json.loads(result_json) + if result[0] > 0: + logger.info(f"Deleted {result[0]} requests") else: logger.info(f"No requests to delete") @@ -311,7 +316,8 @@ async def gc(server: edbserver.BaseServer) -> None: if tenant.accept_new_tasks ] try: - await asyncio.wait(tasks) + if tasks: + await asyncio.wait(tasks) except Exception as ex: logger.debug( "GC of std::net::http::ScheduledRequest failed", exc_info=ex diff --git a/edb/server/protocol/auth_ext/pkce.py b/edb/server/protocol/auth_ext/pkce.py index 028a6e9e162..a8acfdc5752 100644 --- a/edb/server/protocol/auth_ext/pkce.py +++ b/edb/server/protocol/auth_ext/pkce.py @@ -158,23 +158,29 @@ async def delete(db: edbtenant.dbview.Database, id: str) -> None: assert len(result_json) == 1 +async def _delete_challenge(db: edbtenant.dbview.Database) -> None: + if not db.tenant.is_database_connectable(db.name): + # Don't run gc if the database is not connectable, e.g. being dropped + return + + await execute.parse_execute_json( + db, + """ + delete ext::auth::PKCEChallenge filter + (datetime_of_statement() - .created_at) > + $validity + """, + variables={"validity": VALIDITY.to_backend_str()}, + cached_globally=True, + ) + + async def _gc(tenant: edbtenant.Tenant) -> None: try: async with asyncio.TaskGroup() as g: for db in tenant.iter_dbs(): if "auth" in db.extensions: - g.create_task( - execute.parse_execute_json( - db, - """ - delete ext::auth::PKCEChallenge filter - (datetime_of_statement() - .created_at) > - $validity - """, - variables={"validity": VALIDITY.to_backend_str()}, - cached_globally=True, - ), - ) + g.create_task(_delete_challenge(db)) except Exception as ex: logger.debug( "GC of ext::auth::PKCEChallenge failed (instance: %s)",