Skip to content

Commit 757ecbc

Browse files
committed
Global exceptions were silencing CancellationError
1 parent cc0808f commit 757ecbc

File tree

1 file changed

+37
-31
lines changed

1 file changed

+37
-31
lines changed

services/web/server/src/simcore_service_webserver/resource_manager/garbage_collector.py

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
import logging
33
from contextlib import suppress
44
from itertools import chain
5-
from typing import Dict, List, Tuple
5+
from typing import Dict, List, Optional, Tuple
66

7+
import psycopg2
78
from aiohttp import web
8-
from aiopg.sa.result import RowProxy
99
from aioredlock import Aioredlock
10-
1110
from servicelib.observer import emit
1211
from servicelib.utils import logged_gather
1312
from simcore_service_webserver import users_exceptions
@@ -52,33 +51,37 @@
5251
logger = logging.getLogger(__name__)
5352

5453

55-
async def setup_garbage_collector_task(app: web.Application):
56-
loop = asyncio.get_event_loop()
57-
app[APP_GARBAGE_COLLECTOR_KEY] = loop.create_task(garbage_collector_task(app))
54+
async def _setup_garbage_collector_task(app: web.Application):
55+
56+
app[APP_GARBAGE_COLLECTOR_KEY] = asyncio.create_task(
57+
garbage_collector_task(app), name="garbage-collector"
58+
)
59+
5860
yield
59-
task = app[APP_GARBAGE_COLLECTOR_KEY]
60-
task.cancel()
61-
await task
61+
62+
with suppress(asyncio.CancelledError):
63+
task = app[APP_GARBAGE_COLLECTOR_KEY]
64+
task.cancel()
65+
await task
6266

6367

6468
def setup_garbage_collector(app: web.Application):
65-
app.cleanup_ctx.append(setup_garbage_collector_task)
69+
app.cleanup_ctx.append(_setup_garbage_collector_task)
6670

6771

6872
async def garbage_collector_task(app: web.Application):
69-
keep_alive = True
7073

71-
while keep_alive:
74+
while True:
7275
logger.info("Starting garbage collector...")
7376
try:
7477
interval = get_garbage_collector_interval(app)
7578
while True:
7679
await collect_garbage(app)
7780
await asyncio.sleep(interval)
7881

79-
except asyncio.CancelledError:
80-
keep_alive = False
81-
logger.info("Garbage collection task was cancelled, it will not restart!")
82+
except asyncio.CancelledError: # pylint: disable=try-except-raise
83+
# do not catch this
84+
raise
8285

8386
except Exception: # pylint: disable=broad-except
8487
logger.warning(
@@ -254,12 +257,10 @@ async def remove_disconnected_user_resources(
254257
resource_name,
255258
keys_to_update,
256259
)
257-
with suppress(asyncio.CancelledError):
258-
on_released_tasks = [
259-
registry.remove_resource(key, resource_name)
260-
for key in keys_to_update
261-
]
262-
await logged_gather(*on_released_tasks, reraise=False)
260+
on_released_tasks = [
261+
registry.remove_resource(key, resource_name) for key in keys_to_update
262+
]
263+
await logged_gather(*on_released_tasks, reraise=False)
263264

264265
# NOTE:
265266
# - if releasing a resource (1) fails, annotations in registry allows GC to try in next round
@@ -375,11 +376,12 @@ async def remove_guest_user_with_all_its_resources(
375376
try:
376377
await remove_all_projects_for_user(app=app, user_id=user_id)
377378
await remove_user(app=app, user_id=user_id)
378-
except Exception as e: # pylint: disable=broad-except
379-
logger.warning("%s", e)
379+
380+
except psycopg2.DatabaseError:
380381
logger.warning(
381382
"Could not remove GUEST with id=%s. Check the logs above for details",
382383
user_id,
384+
exc_info=True,
383385
)
384386

385387

@@ -405,7 +407,7 @@ async def remove_all_projects_for_user(app: web.Application, user_id: int) -> No
405407
user_id,
406408
)
407409
return
408-
user_primary_gid: str = str(project_owner["primary_gid"])
410+
user_primary_gid = int(project_owner["primary_gid"])
409411

410412
# fetch all projects for the user
411413
user_project_uuids = await app[
@@ -472,8 +474,8 @@ async def get_new_project_owner_gid(
472474
project_uuid: str,
473475
user_id: int,
474476
user_primary_gid: int,
475-
project: RowProxy,
476-
) -> str:
477+
project: Dict,
478+
) -> Optional[int]:
477479
"""Goes through the access rights and tries to find a new suitable owner.
478480
The first viable user is selected as a new owner.
479481
In order to become a new owner the user must have write access right.
@@ -533,7 +535,7 @@ async def get_new_project_owner_gid(
533535

534536
async def fetch_new_project_owner_from_groups(
535537
app: web.Application, standard_groups: Dict, user_id: int
536-
) -> int:
538+
) -> Optional[int]:
537539
"""Iterate over all the users in a group and if the users exists in the db
538540
return its gid"""
539541

@@ -554,6 +556,7 @@ async def fetch_new_project_owner_from_groups(
554556
"Could not find new owner '%s' will try a new one",
555557
possible_user_id,
556558
)
559+
557560
return None
558561

559562

@@ -562,17 +565,19 @@ async def replace_current_owner(
562565
project_uuid: str,
563566
user_primary_gid: int,
564567
new_project_owner_gid: str,
565-
project: RowProxy,
568+
project: Dict,
566569
) -> None:
567570
try:
568571
new_project_owner_id = await get_user_id_from_gid(
569572
app=app, primary_gid=int(new_project_owner_gid)
570573
)
571-
except Exception: # pylint: disable=broad-except
574+
575+
except psycopg2.DatabaseError:
572576
logger.exception(
573577
"Could not recover new user id from gid %s", new_project_owner_gid
574578
)
575579
return
580+
576581
# the result might me none
577582
if new_project_owner_id is None:
578583
logger.warning(
@@ -588,13 +593,14 @@ async def replace_current_owner(
588593
str(new_project_owner_gid)
589594
] = ProjectAccessRights.OWNER.value
590595
logger.error("Syncing back project %s", project)
596+
591597
# syncing back project data
592598
try:
593599
await app[APP_PROJECT_DBAPI].update_project_without_enforcing_checks(
594600
project_data=project,
595601
project_uuid=project_uuid,
596602
)
597-
except Exception: # pylint: disable=broad-except
603+
except psycopg2.DatabaseError:
598604
logger.exception(
599605
"Could not remove old owner and replaced it with user %s",
600606
new_project_owner_id,
@@ -605,7 +611,7 @@ async def remove_user(app: web.Application, user_id: int) -> None:
605611
"""Tries to remove a user, if the users still exists a warning message will be displayed"""
606612
try:
607613
await delete_user(app, user_id)
608-
except Exception: # pylint: disable=broad-except
614+
except psycopg2.DatabaseError:
609615
logger.warning(
610616
"User '%s' still has some projects, could not be deleted", user_id
611617
)

0 commit comments

Comments
 (0)