Skip to content

Commit 503ef0f

Browse files
fix tests
1 parent 4d3d978 commit 503ef0f

File tree

3 files changed

+89
-105
lines changed

3 files changed

+89
-105
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""Utility functions for project document management.
2+
3+
This module contains common utilities for building and versioning project documents.
4+
"""
5+
6+
from typing import cast
7+
8+
from aiohttp import web
9+
from models_library.api_schemas_webserver.projects import ProjectDocument
10+
from models_library.projects import ProjectID, ProjectTemplateType
11+
from models_library.projects import ProjectType as ProjectTypeAPI
12+
from servicelib.redis import (
13+
PROJECT_DB_UPDATE_REDIS_LOCK_KEY,
14+
exclusive,
15+
increment_and_return_project_document_version,
16+
)
17+
18+
from ..redis import (
19+
get_redis_document_manager_client_sdk,
20+
get_redis_lock_manager_client_sdk,
21+
)
22+
from . import _projects_repository
23+
24+
25+
async def build_project_document_and_increment_version(
26+
app: web.Application, project_uuid: ProjectID
27+
) -> tuple[ProjectDocument, int]:
28+
"""Build project document and increment version with Redis lock protection.
29+
30+
This function is protected by Redis exclusive lock because:
31+
- the project document and its version must be kept in sync
32+
33+
Args:
34+
app: The web application instance
35+
project_uuid: UUID of the project
36+
37+
Returns:
38+
Tuple containing the project document and its version number
39+
"""
40+
41+
@exclusive(
42+
get_redis_lock_manager_client_sdk(app),
43+
lock_key=PROJECT_DB_UPDATE_REDIS_LOCK_KEY.format(project_uuid),
44+
blocking=True,
45+
blocking_timeout=None, # NOTE: this is a blocking call, a timeout has undefined effects
46+
)
47+
async def _build_project_document_and_increment_version() -> (
48+
tuple[ProjectDocument, int]
49+
):
50+
"""This function is protected because
51+
- the project document and its version must be kept in sync
52+
"""
53+
# Get the full project with workbench for document creation
54+
project_with_workbench = await _projects_repository.get_project_with_workbench(
55+
app=app, project_uuid=project_uuid
56+
)
57+
# Create project document
58+
project_document = ProjectDocument(
59+
uuid=project_with_workbench.uuid,
60+
workspace_id=project_with_workbench.workspace_id,
61+
name=project_with_workbench.name,
62+
description=project_with_workbench.description,
63+
thumbnail=project_with_workbench.thumbnail,
64+
last_change_date=project_with_workbench.last_change_date,
65+
classifiers=project_with_workbench.classifiers,
66+
dev=project_with_workbench.dev,
67+
quality=project_with_workbench.quality,
68+
workbench=project_with_workbench.workbench,
69+
ui=project_with_workbench.ui,
70+
type=cast(ProjectTypeAPI, project_with_workbench.type),
71+
template_type=cast(
72+
ProjectTemplateType, project_with_workbench.template_type
73+
),
74+
)
75+
# Increment document version
76+
redis_client_sdk = get_redis_document_manager_client_sdk(app)
77+
document_version = await increment_and_return_project_document_version(
78+
redis_client=redis_client_sdk, project_uuid=project_uuid
79+
)
80+
81+
return project_document, document_version
82+
83+
return await _build_project_document_and_increment_version()

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

Lines changed: 2 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from aiopg.sa import Engine
1616
from aiopg.sa.connection import SAConnection
1717
from aiopg.sa.result import ResultProxy, RowProxy
18-
from models_library.api_schemas_webserver.projects import ProjectDocument
1918
from models_library.basic_types import IDStr
2019
from models_library.folders import FolderQuery, FolderScope
2120
from models_library.groups import GroupID
@@ -26,7 +25,6 @@
2625
ProjectListAtDB,
2726
ProjectTemplateType,
2827
)
29-
from models_library.projects import ProjectType as ProjectTypeAPI
3028
from models_library.projects_comments import CommentID, ProjectsCommentsDB
3129
from models_library.projects_nodes import Node
3230
from models_library.projects_nodes_io import NodeID, NodeIDStr
@@ -44,11 +42,6 @@
4442
from pydantic.types import PositiveInt
4543
from servicelib.aiohttp.application_keys import APP_AIOPG_ENGINE_KEY
4644
from servicelib.logging_utils import get_log_record_extra, log_context
47-
from servicelib.redis import (
48-
PROJECT_DB_UPDATE_REDIS_LOCK_KEY,
49-
exclusive,
50-
increment_and_return_project_document_version,
51-
)
5245
from simcore_postgres_database.aiopg_errors import UniqueViolation
5346
from simcore_postgres_database.models.groups import user_to_groups
5447
from simcore_postgres_database.models.project_to_groups import project_to_groups
@@ -82,12 +75,7 @@
8275
from tenacity.asyncio import AsyncRetrying
8376
from tenacity.retry import retry_if_exception_type
8477

85-
from ..redis import (
86-
get_redis_document_manager_client_sdk,
87-
get_redis_lock_manager_client_sdk,
88-
)
8978
from ..utils import now_str
90-
from . import _projects_repository
9179
from ._comments_repository import (
9280
create_project_comment,
9381
delete_project_comment,
@@ -96,6 +84,7 @@
9684
total_project_comments,
9785
update_project_comment,
9886
)
87+
from ._project_document_utils import build_project_document_and_increment_version
9988
from ._projects_repository import PROJECT_DB_COLS
10089
from ._projects_repository_legacy_utils import (
10190
ANY_USER_ID_SENTINEL,
@@ -967,54 +956,10 @@ async def _update_project_workbench_with_lock_and_notify(
967956
allow_workbench_changes=allow_workbench_changes,
968957
)
969958

970-
@exclusive(
971-
get_redis_lock_manager_client_sdk(self._app),
972-
lock_key=PROJECT_DB_UPDATE_REDIS_LOCK_KEY.format(project_uuid),
973-
blocking=True,
974-
blocking_timeout=None, # NOTE: this is a blocking call, a timeout has undefined effects
975-
)
976-
async def _build_project_document_and_increment_version() -> (
977-
tuple[ProjectDocument, int]
978-
):
979-
"""This function is protected because
980-
- the project document and its version must be kept in sync
981-
"""
982-
# Get the full project with workbench for document creation
983-
project_with_workbench = (
984-
await _projects_repository.get_project_with_workbench(
985-
app=self._app, project_uuid=project_uuid
986-
)
987-
)
988-
# Create project document
989-
project_document = ProjectDocument(
990-
uuid=project_with_workbench.uuid,
991-
workspace_id=project_with_workbench.workspace_id,
992-
name=project_with_workbench.name,
993-
description=project_with_workbench.description,
994-
thumbnail=project_with_workbench.thumbnail,
995-
last_change_date=project_with_workbench.last_change_date,
996-
classifiers=project_with_workbench.classifiers,
997-
dev=project_with_workbench.dev,
998-
quality=project_with_workbench.quality,
999-
workbench=project_with_workbench.workbench,
1000-
ui=project_with_workbench.ui,
1001-
type=cast(ProjectTypeAPI, project_with_workbench.type),
1002-
template_type=cast(
1003-
ProjectTemplateType, project_with_workbench.template_type
1004-
),
1005-
)
1006-
# Increment document version
1007-
redis_client_sdk = get_redis_document_manager_client_sdk(self._app)
1008-
document_version = await increment_and_return_project_document_version(
1009-
redis_client=redis_client_sdk, project_uuid=project_uuid
1010-
)
1011-
1012-
return project_document, document_version
1013-
1014959
(
1015960
project_document,
1016961
document_version,
1017-
) = await _build_project_document_and_increment_version()
962+
) = await build_project_document_and_increment_version(self._app, project_uuid)
1018963

1019964
await notify_project_document_updated(
1020965
app=self._app,

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

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
DynamicServiceStop,
3131
)
3232
from models_library.api_schemas_webserver.projects import (
33-
ProjectDocument,
3433
ProjectGet,
3534
ProjectPatch,
3635
)
@@ -39,8 +38,7 @@
3938
from models_library.errors import ErrorDict
4039
from models_library.groups import GroupID
4140
from models_library.products import ProductName
42-
from models_library.projects import Project, ProjectID, ProjectTemplateType
43-
from models_library.projects import ProjectType as ProjectTypeAPI
41+
from models_library.projects import Project, ProjectID
4442
from models_library.projects_access import Owner
4543
from models_library.projects_nodes import Node, NodeState, PartialNode
4644
from models_library.projects_nodes_io import NodeID, NodeIDStr, PortLink
@@ -85,10 +83,8 @@
8583
ServiceWasNotFoundError,
8684
)
8785
from servicelib.redis import (
88-
PROJECT_DB_UPDATE_REDIS_LOCK_KEY,
8986
exclusive,
9087
get_project_locked_state,
91-
increment_and_return_project_document_version,
9288
is_project_locked,
9389
with_project_locked,
9490
)
@@ -107,10 +103,7 @@
107103
from ..dynamic_scheduler import api as dynamic_scheduler_service
108104
from ..products import products_web
109105
from ..rabbitmq import get_rabbitmq_rpc_client
110-
from ..redis import (
111-
get_redis_document_manager_client_sdk,
112-
get_redis_lock_manager_client_sdk,
113-
)
106+
from ..redis import get_redis_lock_manager_client_sdk
114107
from ..resource_manager.models import UserSession
115108
from ..resource_manager.user_sessions import (
116109
PROJECT_ID_KEY,
@@ -146,6 +139,7 @@
146139
has_user_project_access_rights,
147140
)
148141
from ._nodes_utils import set_reservation_same_as_limit, validate_new_service_resources
142+
from ._project_document_utils import build_project_document_and_increment_version
149143
from ._projects_repository_legacy import APP_PROJECT_DBAPI, ProjectDBAPI
150144
from ._projects_repository_legacy_utils import PermissionStr
151145
from ._socketio_service import notify_project_document_updated
@@ -209,46 +203,8 @@ async def patch_project_and_notify_users(
209203
new_partial_project_data=patch_project_data,
210204
)
211205

212-
@exclusive(
213-
get_redis_lock_manager_client_sdk(app),
214-
lock_key=PROJECT_DB_UPDATE_REDIS_LOCK_KEY.format(project_uuid),
215-
blocking=True,
216-
blocking_timeout=None, # NOTE: this is a blocking call, a timeout has undefined effects
217-
)
218-
async def _build_project_document_and_increment_version() -> (
219-
tuple[ProjectDocument, int]
220-
):
221-
"""This function is protected because
222-
- the project document and its version must be kept in sync
223-
"""
224-
project_with_workbench = await _projects_repository.get_project_with_workbench(
225-
app=app, project_uuid=project_uuid
226-
)
227-
project_document = ProjectDocument(
228-
uuid=project_with_workbench.uuid,
229-
workspace_id=project_with_workbench.workspace_id,
230-
name=project_with_workbench.name,
231-
description=project_with_workbench.description,
232-
thumbnail=project_with_workbench.thumbnail,
233-
last_change_date=project_with_workbench.last_change_date,
234-
classifiers=project_with_workbench.classifiers,
235-
dev=project_with_workbench.dev,
236-
quality=project_with_workbench.quality,
237-
workbench=project_with_workbench.workbench,
238-
ui=project_with_workbench.ui,
239-
type=cast(ProjectTypeAPI, project_with_workbench.type),
240-
template_type=cast(
241-
ProjectTemplateType, project_with_workbench.template_type
242-
),
243-
)
244-
redis_client_sdk = get_redis_document_manager_client_sdk(app)
245-
document_version = await increment_and_return_project_document_version(
246-
redis_client=redis_client_sdk, project_uuid=project_uuid
247-
)
248-
return project_document, document_version
249-
250206
project_document, document_version = (
251-
await _build_project_document_and_increment_version()
207+
await build_project_document_and_increment_version(app, project_uuid)
252208
)
253209
await notify_project_document_updated(
254210
app=app,

0 commit comments

Comments
 (0)