@@ -1354,7 +1354,7 @@ async def post_trigger_connected_service_retrieve(
13541354#
13551355
13561356
1357- async def _user_has_another_client_open (
1357+ async def _user_has_another_active_session (
13581358 users_sessions_ids : list [UserSessionID ], app : web .Application
13591359) -> bool :
13601360 # NOTE if there is an active socket in use, that means the client is active
@@ -1394,7 +1394,7 @@ async def try_open_project_for_user(
13941394 client_session_id : str ,
13951395 app : web .Application ,
13961396 max_number_of_opened_projects_per_user : int | None ,
1397- max_number_of_users_per_project : PositiveInt | None ,
1397+ max_number_of_user_sessions_per_project : PositiveInt | None ,
13981398) -> bool :
13991399 """
14001400 Raises:
@@ -1417,8 +1417,7 @@ async def try_open_project_for_user(
14171417 )
14181418 async def _open_project () -> bool :
14191419 with managed_resource (user_id , client_session_id , app ) as user_session :
1420- # NOTE: if max_number_of_studies_per_user is set, the same
1421- # project shall still be openable if the tab was closed
1420+ # Enforce per-user open project limit
14221421 if max_number_of_opened_projects_per_user is not None and (
14231422 len (
14241423 {
@@ -1439,35 +1438,39 @@ async def _open_project() -> bool:
14391438 )
14401439
14411440 # Assign project_id to current_session
1442- current_session : UserSessionID = user_session .get_id ()
1443- sessions_with_project : list [UserSessionID ] = (
1444- await user_session .find_users_of_resource (
1445- app , PROJECT_ID_KEY , f"{ project_uuid } "
1446- )
1441+ sessions_with_project = await user_session .find_users_of_resource (
1442+ app , PROJECT_ID_KEY , f"{ project_uuid } "
14471443 )
1448- if not sessions_with_project :
1444+ if (
1445+ max_number_of_user_sessions_per_project is None
1446+ or not sessions_with_project
1447+ ) or (
1448+ len (sessions_with_project ) < max_number_of_user_sessions_per_project
1449+ ):
14491450 # no one has the project so we assign it
14501451 await user_session .add (PROJECT_ID_KEY , f"{ project_uuid } " )
14511452 return True
14521453
1453- # Otherwise if this is the only user (NOTE: a session = user_id + client_seesion_id !)
1454- user_ids : set [int ] = {s .user_id for s in sessions_with_project }
1455- if user_ids .issubset ({user_id }):
1456- other_sessions_with_project = [
1457- usid
1458- for usid in sessions_with_project
1459- if usid != current_session
1460- ]
1461- if not await _user_has_another_client_open (
1462- other_sessions_with_project ,
1463- app ,
1464- ):
1465- # steal the project
1466- await user_session .add (PROJECT_ID_KEY , f"{ project_uuid } " )
1467- await _clean_user_disconnected_clients (
1468- sessions_with_project , app
1469- )
1470- return True
1454+ # NOTE: Special case for backwards compatibility, allow to close a tab and open the project again in a new tab
1455+ if max_number_of_user_sessions_per_project == 1 :
1456+ current_session = user_session .get_id ()
1457+ user_ids : set [int ] = {s .user_id for s in sessions_with_project }
1458+ if user_ids .issubset ({user_id }):
1459+ other_sessions_with_project = [
1460+ usid
1461+ for usid in sessions_with_project
1462+ if usid != current_session
1463+ ]
1464+ if not await _user_has_another_active_session (
1465+ other_sessions_with_project ,
1466+ app ,
1467+ ):
1468+ # steal the project
1469+ await user_session .add (PROJECT_ID_KEY , f"{ project_uuid } " )
1470+ await _clean_user_disconnected_clients (
1471+ sessions_with_project , app
1472+ )
1473+ return True
14711474
14721475 return False
14731476
@@ -1591,7 +1594,7 @@ async def _get_project_lock_state(
15911594 await users_service .get_user_fullname (app , user_id = uid ) for uid in set_user_ids
15921595 ]
15931596 # let's check if the project is opened by the same user, maybe already opened or closed in a orphaned session
1594- if set_user_ids .issubset ({user_id }) and not await _user_has_another_client_open (
1597+ if set_user_ids .issubset ({user_id }) and not await _user_has_another_active_session (
15951598 user_session_id_list , app
15961599 ):
15971600 # in this case the project is re-openable by the same user until it gets closed
0 commit comments