Skip to content

Commit 03ecfe7

Browse files
committed
new share state
1 parent 00daad0 commit 03ecfe7

File tree

1 file changed

+40
-46
lines changed

1 file changed

+40
-46
lines changed

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

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
from models_library.projects_nodes import Node, NodeState, PartialNode
4040
from models_library.projects_nodes_io import NodeID, NodeIDStr, PortLink
4141
from models_library.projects_state import (
42-
ProjectLocked,
4342
ProjectRunningState,
43+
ProjectShareState,
4444
ProjectState,
4545
ProjectStatus,
4646
RunningState,
@@ -84,7 +84,7 @@
8484
is_project_locked,
8585
with_project_locked,
8686
)
87-
from servicelib.utils import fire_and_forget_task, logged_gather
87+
from servicelib.utils import fire_and_forget_task, limited_gather, logged_gather
8888
from simcore_postgres_database.models.users import UserRole
8989
from simcore_postgres_database.utils_projects_nodes import (
9090
ProjectNodeCreate,
@@ -1500,31 +1500,44 @@ async def try_close_project_for_user(
15001500
)
15011501

15021502

1503-
async def _get_project_lock_state(
1503+
async def _get_project_share_state(
15041504
user_id: int,
15051505
project_uuid: str,
15061506
app: web.Application,
1507-
) -> ProjectLocked:
1507+
) -> ProjectShareState:
15081508
"""returns the lock state of a project
15091509
1. If a project is locked for any reason, first return the project as locked and STATUS defined by lock
1510-
2. If a client_session_id is passed, then first check to see if the project is currently opened by this very user/tab combination, if yes returns the project as Locked and OPENED.
15111510
3. If any other user than user_id is using the project (even disconnected before the TTL is finished) then the project is Locked and OPENED.
15121511
4. If the same user is using the project with a valid socket id (meaning a tab is currently active) then the project is Locked and OPENED.
15131512
5. If the same user is using the project with NO socket id (meaning there is no current tab active) then the project is Unlocked and OPENED. which means the user can open it again.
15141513
"""
1515-
log.debug(
1516-
"getting project [%s] lock state for user [%s]...",
1517-
f"{project_uuid=}",
1518-
f"{user_id=}",
1519-
)
15201514
prj_locked_state = await get_project_locked_state(
15211515
get_redis_lock_manager_client_sdk(app), project_uuid
15221516
)
15231517
if prj_locked_state:
15241518
log.debug(
1525-
"project [%s] is locked: %s", f"{project_uuid=}", f"{prj_locked_state=}"
1519+
"project [%s] is currently locked: %s",
1520+
f"{project_uuid=}",
1521+
f"{prj_locked_state=}",
1522+
)
1523+
return ProjectShareState(
1524+
status=prj_locked_state.status,
1525+
locked=prj_locked_state.status
1526+
in [
1527+
ProjectStatus.CLONING,
1528+
ProjectStatus.EXPORTING,
1529+
ProjectStatus.MAINTAINING,
1530+
],
1531+
current_user_groupids=(
1532+
[
1533+
await users_service.get_user_primary_group_id(
1534+
app, prj_locked_state.owner.user_id
1535+
)
1536+
]
1537+
if prj_locked_state.owner
1538+
else []
1539+
),
15261540
)
1527-
return prj_locked_state
15281541

15291542
# let's now check if anyone has the project in use somehow
15301543
with managed_resource(user_id, None, app) as rt:
@@ -1533,48 +1546,29 @@ async def _get_project_lock_state(
15331546
)
15341547
set_user_ids = {user_session.user_id for user_session in user_sessions_with_project}
15351548

1536-
assert ( # nosec
1537-
len(set_user_ids) <= 1
1538-
) # nosec # NOTE: A project can only be opened by one user in one tab at the moment
1539-
15401549
if not set_user_ids:
15411550
# no one has the project, so it is unlocked and closed.
15421551
log.debug("project [%s] is not in use", f"{project_uuid=}")
1543-
return ProjectLocked(value=False, status=ProjectStatus.CLOSED)
1552+
return ProjectShareState(
1553+
status=ProjectStatus.CLOSED, locked=False, current_user_groupids=[]
1554+
)
15441555

15451556
log.debug(
15461557
"project [%s] might be used by the following users: [%s]",
15471558
f"{project_uuid=}",
15481559
f"{set_user_ids=}",
15491560
)
1550-
usernames = [
1551-
await users_service.get_user_fullname(app, user_id=uid) for uid in set_user_ids
1552-
]
1553-
# let's check if the project is opened by the same user, maybe already opened or closed in a orphaned session
1554-
if set_user_ids.issubset({user_id}) and not await _user_has_another_active_session(
1555-
user_sessions_with_project, app
1556-
):
1557-
# in this case the project is re-openable by the same user until it gets closed
1558-
log.debug(
1559-
"project [%s] is in use by the same user [%s] that is currently disconnected, so it is unlocked for this specific user and opened",
1560-
f"{project_uuid=}",
1561-
f"{set_user_ids=}",
1562-
)
1563-
return ProjectLocked(
1564-
value=False,
1565-
owner=Owner(user_id=next(iter(set_user_ids)), **usernames[0]),
1566-
status=ProjectStatus.OPENED,
1567-
)
1568-
# the project is opened in another tab or browser, or by another user, both case resolves to the project being locked, and opened
1569-
log.debug(
1570-
"project [%s] is in use by another user [%s], so it is locked",
1571-
f"{project_uuid=}",
1572-
f"{set_user_ids=}",
1573-
)
1574-
return ProjectLocked(
1575-
value=True,
1576-
owner=Owner(user_id=next(iter(set_user_ids)), **usernames[0]),
1561+
1562+
return ProjectShareState(
15771563
status=ProjectStatus.OPENED,
1564+
locked=False,
1565+
current_user_groupids=await limited_gather(
1566+
*[
1567+
users_service.get_user_primary_group_id(app, user_id=uid)
1568+
for uid in set_user_ids
1569+
],
1570+
limit=10,
1571+
),
15781572
)
15791573

15801574

@@ -1584,7 +1578,7 @@ async def get_project_states_for_user(
15841578
# for templates: the project is never locked and never opened. also the running state is always unknown
15851579
running_state = RunningState.UNKNOWN
15861580
lock_state, computation_task = await logged_gather(
1587-
_get_project_lock_state(user_id, project_uuid, app),
1581+
_get_project_share_state(user_id, project_uuid, app),
15881582
director_v2_service.get_computation_task(app, user_id, UUID(project_uuid)),
15891583
)
15901584
if computation_task:
@@ -1609,7 +1603,7 @@ async def add_project_states_for_user(
16091603
f"{project['uuid']=}",
16101604
)
16111605
# for templates: the project is never locked and never opened. also the running state is always unknown
1612-
lock_state = await _get_project_lock_state(user_id, project["uuid"], app)
1606+
lock_state = await _get_project_share_state(user_id, project["uuid"], app)
16131607
running_state = RunningState.UNKNOWN
16141608

16151609
if not is_template and (

0 commit comments

Comments
 (0)