2929from ai .backend .common .identifier .deployment_preset import DeploymentPresetID
3030from ai .backend .common .identifier .deployment_revision import DeploymentRevisionID
3131from ai .backend .common .identifier .image import ImageID
32+ from ai .backend .common .identifier .replica import ReplicaID
3233from ai .backend .common .identifier .resource_group import ResourceGroupName
3334from ai .backend .common .identifier .runtime_variant import RuntimeVariantID
3435from ai .backend .common .identifier .vfolder import VFolderUUID
179180 ProjectDeploymentSearchScope ,
180181 RouteData ,
181182 RouteServiceDiscoveryInfo ,
183+ RouteSessionInfo ,
184+ RouteSessionKernelInfo ,
182185)
183186from ai .backend .manager .repositories .scheduler .types .session_creation import (
184187 ContainerUserContext ,
@@ -1208,7 +1211,7 @@ async def get_endpoint_id_by_session(
12081211
12091212 async def fetch_route_service_discovery_info (
12101213 self ,
1211- route_ids : set [uuid . UUID ],
1214+ route_ids : set [ReplicaID ],
12121215 ) -> list [RouteServiceDiscoveryInfo ]:
12131216 """Fetch service discovery information for routes.
12141217
@@ -1770,9 +1773,9 @@ async def update_route_status_bulk_with_history(
17701773 async def _get_last_route_histories_by_category (
17711774 self ,
17721775 db_sess : SASession ,
1773- route_ids : list [uuid . UUID ],
1776+ route_ids : list [ReplicaID ],
17741777 category : RouteHandlerCategory ,
1775- ) -> dict [uuid . UUID , RouteHistoryRow ]:
1778+ ) -> dict [ReplicaID , RouteHistoryRow ]:
17761779 """Get last history records per route filtered by handler category."""
17771780 if not route_ids :
17781781 return {}
@@ -1796,8 +1799,8 @@ async def _get_last_route_histories_by_category(
17961799 async def _get_last_route_histories_bulk (
17971800 self ,
17981801 db_sess : SASession ,
1799- route_ids : list [uuid . UUID ],
1800- ) -> dict [uuid . UUID , RouteHistoryRow ]:
1802+ route_ids : list [ReplicaID ],
1803+ ) -> dict [ReplicaID , RouteHistoryRow ]:
18011804 """Get last history records for multiple routes efficiently."""
18021805 if not route_ids :
18031806 return {}
@@ -1927,15 +1930,15 @@ async def fetch_kernel_connection_info(
19271930
19281931 async def update_route_replica_info (
19291932 self ,
1930- updates : dict [uuid . UUID , tuple [ str , int ] ],
1933+ updates : dict [ReplicaID , RouteSessionKernelInfo ],
19311934 ) -> None :
19321935 """Update replica_host and replica_port for routes."""
19331936 async with self ._begin_session_read_committed () as db_sess :
1934- for route_id , ( host , port ) in updates .items ():
1937+ for route_id , kernel in updates .items ():
19351938 query = (
19361939 sa .update (RoutingRow )
19371940 .where (RoutingRow .id == route_id )
1938- .values (replica_host = host , replica_port = port )
1941+ .values (replica_host = kernel . replica_host , replica_port = kernel . replica_port )
19391942 )
19401943 await db_sess .execute (query )
19411944
@@ -2129,8 +2132,8 @@ async def fetch_deployment_context(
21292132
21302133 async def fetch_session_statuses_by_route_ids (
21312134 self ,
2132- route_ids : set [uuid . UUID ],
2133- ) -> Mapping [uuid . UUID , SessionStatus | None ]:
2135+ route_ids : set [ReplicaID ],
2136+ ) -> Mapping [ReplicaID , SessionStatus | None ]:
21342137 """Fetch session statuses for multiple routes.
21352138
21362139 Args:
@@ -2158,12 +2161,83 @@ async def fetch_session_statuses_by_route_ids(
21582161 rows = result .all ()
21592162
21602163 # 결과를 매핑으로 변환
2161- status_map : dict [uuid . UUID , SessionStatus | None ] = {}
2164+ status_map : dict [ReplicaID , SessionStatus | None ] = {}
21622165 for route_id , session_status in rows :
2163- status_map [route_id ] = session_status
2166+ status_map [ReplicaID ( route_id ) ] = session_status
21642167
21652168 return status_map
21662169
2170+ async def fetch_route_session_kernel_infos (
2171+ self ,
2172+ route_ids : set [ReplicaID ],
2173+ ) -> Mapping [ReplicaID , RouteSessionInfo | None ]:
2174+ """Fetch session status and kernel connection info for multiple routes.
2175+
2176+ Args:
2177+ route_ids: Set of route IDs to fetch information for
2178+
2179+ Returns:
2180+ Mapping of route_id to RouteSessionInfo:
2181+ - None → route has no session linked
2182+ - RouteSessionInfo(status=TERMINAL, kernel=None) → session terminated
2183+ - RouteSessionInfo(status=RUNNING, kernel=RouteSessionKernelInfo(host, port)) → ready
2184+ - RouteSessionInfo(status=PREPARING, kernel=None) → not yet running
2185+ """
2186+ if not route_ids :
2187+ return {}
2188+
2189+ async with self ._begin_readonly_session_read_committed () as db_sess :
2190+ query = (
2191+ sa .select (
2192+ RoutingRow .id ,
2193+ SessionRow .status ,
2194+ KernelRow .kernel_host ,
2195+ KernelRow .service_ports ,
2196+ )
2197+ .select_from (RoutingRow )
2198+ .outerjoin (SessionRow , RoutingRow .session == SessionRow .id )
2199+ .outerjoin (
2200+ KernelRow ,
2201+ sa .and_ (
2202+ KernelRow .session_id == RoutingRow .session ,
2203+ KernelRow .cluster_role == "main" ,
2204+ ),
2205+ )
2206+ .where (RoutingRow .id .in_ (route_ids ))
2207+ )
2208+
2209+ result = await db_sess .execute (query )
2210+ rows = result .all ()
2211+
2212+ info_map : dict [ReplicaID , RouteSessionInfo | None ] = {}
2213+ for row in rows :
2214+ route_id = ReplicaID (row .id )
2215+ if row .status is None :
2216+ info_map [route_id ] = None
2217+ continue
2218+
2219+ kernel : RouteSessionKernelInfo | None = None
2220+ if row .kernel_host and row .service_ports :
2221+ inference_port : int | None = None
2222+ for port_info in row .service_ports :
2223+ if port_info .get ("is_inference" , False ):
2224+ host_ports = port_info .get ("host_ports" , [])
2225+ if host_ports :
2226+ inference_port = host_ports [0 ]
2227+ break
2228+ if inference_port is not None :
2229+ kernel = RouteSessionKernelInfo (
2230+ replica_host = row .kernel_host ,
2231+ replica_port = inference_port ,
2232+ )
2233+
2234+ info_map [route_id ] = RouteSessionInfo (
2235+ status = row .status ,
2236+ kernel = kernel ,
2237+ )
2238+
2239+ return info_map
2240+
21672241 async def fetch_route_connection_infos (
21682242 self ,
21692243 * ,
0 commit comments