Skip to content

Commit 9740b2f

Browse files
committed
refactoring
1 parent ae4bdb6 commit 9740b2f

File tree

5 files changed

+90
-128
lines changed

5 files changed

+90
-128
lines changed

packages/service-library/src/servicelib/project_lock.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,26 @@ async def _exclusive_func(*args, **kwargs) -> R:
5555
return _wrapper
5656

5757
return _decorator
58+
59+
60+
async def is_project_locked(
61+
redis_client: RedisClientSDK, project_uuid: str | ProjectID
62+
) -> bool:
63+
redis_lock = redis_client.create_lock(PROJECT_REDIS_LOCK_KEY.format(project_uuid))
64+
return await redis_lock.locked()
65+
66+
67+
async def get_project_locked_state(
68+
redis_client: RedisClientSDK, project_uuid: str | ProjectID
69+
) -> ProjectLocked | None:
70+
"""
71+
Returns:
72+
ProjectLocked object if the project project_uuid is locked or None otherwise
73+
"""
74+
if await is_project_locked(redis_client, project_uuid=project_uuid) and (
75+
lock_value := await redis_client.redis.get(
76+
PROJECT_REDIS_LOCK_KEY.format(project_uuid)
77+
)
78+
):
79+
return ProjectLocked.model_validate_json(lock_value)
80+
return None

services/web/server/src/simcore_service_webserver/projects/_crud_handlers.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" Handlers for STANDARD methods on /projects colletions
1+
"""Handlers for STANDARD methods on /projects colletions
22
33
Standard methods or CRUD that states for Create+Read(Get&List)+Update+Delete
44
@@ -36,12 +36,14 @@
3636
X_SIMCORE_USER_AGENT,
3737
)
3838
from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON
39+
from servicelib.project_lock import get_project_locked_state
3940
from servicelib.rest_constants import RESPONSE_MODEL_POLICY
4041

4142
from .._meta import API_VTAG as VTAG
4243
from ..catalog.client import get_services_for_user_in_product
4344
from ..folders.errors import FolderAccessForbiddenError, FolderNotFoundError
4445
from ..login.decorators import login_required
46+
from ..redis import get_redis_lock_manager_client_sdk
4547
from ..resource_manager.user_sessions import PROJECT_ID_KEY, managed_resource
4648
from ..security.api import check_user_permission
4749
from ..security.decorators import permission_required
@@ -65,7 +67,6 @@
6567
ProjectOwnerNotFoundInTheProjectAccessRightsError,
6668
WrongTagIdsInQueryError,
6769
)
68-
from .lock import get_project_locked_state
6970
from .models import ProjectDict
7071
from .utils import get_project_unavailable_services, project_uses_available_services
7172

@@ -139,7 +140,8 @@ async def create_project(request: web.Request):
139140
project_create: (
140141
ProjectCreateNew | ProjectCopyOverride | EmptyModel
141142
) = await parse_request_body_as(
142-
ProjectCreateNew | ProjectCopyOverride | EmptyModel, request # type: ignore[arg-type] # from pydantic v2 --> https://github.com/pydantic/pydantic/discussions/4950
143+
ProjectCreateNew | ProjectCopyOverride | EmptyModel,
144+
request, # type: ignore[arg-type] # from pydantic v2 --> https://github.com/pydantic/pydantic/discussions/4950
143145
)
144146
predefined_project = (
145147
project_create.model_dump(
@@ -457,7 +459,7 @@ async def delete_project(request: web.Request):
457459
)
458460
if project_users:
459461
other_user_names = {
460-
await get_user_fullname(request.app, user_id=uid)
462+
f"{await get_user_fullname(request.app, user_id=uid)}"
461463
for uid in project_users
462464
}
463465
raise web.HTTPForbidden(
@@ -467,7 +469,8 @@ async def delete_project(request: web.Request):
467469

468470
project_locked_state: ProjectLocked | None
469471
if project_locked_state := await get_project_locked_state(
470-
app=request.app, project_uuid=path_params.project_id
472+
get_redis_lock_manager_client_sdk(request.app),
473+
project_uuid=path_params.project_id,
471474
):
472475
raise web.HTTPConflict(
473476
reason=f"Project {path_params.project_id} is locked: {project_locked_state=}"

services/web/server/src/simcore_service_webserver/projects/lock.py

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

services/web/server/src/simcore_service_webserver/projects/projects_api.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@
7272
X_SIMCORE_USER_AGENT,
7373
)
7474
from servicelib.logging_utils import get_log_record_extra, log_context
75+
from servicelib.project_lock import (
76+
get_project_locked_state,
77+
is_project_locked,
78+
with_project_locked,
79+
)
7580
from servicelib.rabbitmq import RemoteMethodNotRegisteredError, RPCServerError
7681
from servicelib.rabbitmq.rpc_interfaces.catalog import services as catalog_rpc
7782
from servicelib.rabbitmq.rpc_interfaces.clusters_keeper.ec2_instances import (
@@ -145,11 +150,6 @@
145150
ProjectStartsTooManyDynamicNodesError,
146151
ProjectTooManyProjectOpenedError,
147152
)
148-
from .lock import (
149-
get_project_locked_state,
150-
is_project_locked,
151-
with_locked_project_from_app,
152-
)
153153
from .models import ProjectDict, ProjectPatchExtended
154154
from .settings import ProjectsSettings, get_plugin_settings
155155
from .utils import extract_dns_without_default_port
@@ -286,7 +286,7 @@ async def patch_project(
286286
"delete": True,
287287
}
288288
user: dict = await get_user(app, project_db.prj_owner)
289-
_prj_owner_primary_group = f'{user["primary_gid"]}'
289+
_prj_owner_primary_group = f"{user['primary_gid']}"
290290
if _prj_owner_primary_group not in new_prj_access_rights:
291291
raise ProjectOwnerNotFoundInTheProjectAccessRightsError
292292
if new_prj_access_rights[_prj_owner_primary_group] != _prj_required_permissions:
@@ -1154,7 +1154,7 @@ async def _trigger_connected_service_retrieve(
11541154
app: web.Application, project: dict, updated_node_uuid: str, changed_keys: list[str]
11551155
) -> None:
11561156
project_id = project["uuid"]
1157-
if await is_project_locked(app, project_id):
1157+
if await is_project_locked(get_redis_lock_manager_client_sdk(app), project_id):
11581158
# NOTE: we log warn since this function is fire&forget and raise an exception would not be anybody to handle it
11591159
log.warning(
11601160
"Skipping service retrieval because project with %s is currently locked."
@@ -1409,7 +1409,7 @@ async def _get_project_lock_state(
14091409
f"{user_id=}",
14101410
)
14111411
prj_locked_state: ProjectLocked | None = await get_project_locked_state(
1412-
app, project_uuid
1412+
get_redis_lock_manager_client_sdk(app), project_uuid
14131413
)
14141414
if prj_locked_state:
14151415
log.debug(
@@ -1880,12 +1880,11 @@ def _decorator(
18801880
) -> Callable[P, Coroutine[Any, Any, R]]:
18811881
@wraps(func)
18821882
async def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
1883-
@with_locked_project_from_app(
1884-
app,
1883+
@with_project_locked(
1884+
get_redis_lock_manager_client_sdk(app),
18851885
project_uuid=project_uuid,
18861886
status=status,
1887-
user_id=user_id,
1888-
user_fullname=user_name,
1887+
owner=Owner(user_id=user_id, **user_name),
18891888
)
18901889
async def _locked_func() -> R:
18911890
if notify_users:

0 commit comments

Comments
 (0)