@@ -930,6 +930,8 @@ pub enum LocalSessionWorkerError {
930930 FailToHandleMessage ( SessionError ) ,
931931 #[ error( "keep alive timeout after {}ms" , _0. as_millis( ) ) ]
932932 KeepAliveTimeout ( Duration ) ,
933+ #[ error( "init timeout after {}ms" , _0. as_millis( ) ) ]
934+ InitTimeout ( Duration ) ,
933935 #[ error( "Transport closed" ) ]
934936 TransportClosed ,
935937 #[ error( "Tokio join error {0}" ) ]
@@ -959,13 +961,24 @@ impl Worker for LocalSessionWorker {
959961 FromHttpService ( SessionEvent ) ,
960962 FromHandler ( WorkerSendRequest < LocalSessionWorker > ) ,
961963 }
962- // waiting for initialize request
963- let evt = self . event_rx . recv ( ) . await . ok_or_else ( || {
964- WorkerQuitReason :: fatal (
965- LocalSessionWorkerError :: TransportTerminated ,
966- "get initialize request" ,
967- )
968- } ) ?;
964+ let init_timeout = self . session_config . init_timeout . unwrap_or ( Duration :: MAX ) ;
965+ let evt = tokio:: select! {
966+ evt = self . event_rx. recv( ) => evt. ok_or_else( || {
967+ WorkerQuitReason :: fatal(
968+ LocalSessionWorkerError :: TransportTerminated ,
969+ "get initialize request" ,
970+ )
971+ } ) ?,
972+ _ = context. cancellation_token. cancelled( ) => {
973+ return Err ( WorkerQuitReason :: Cancelled ) ;
974+ }
975+ _ = tokio:: time:: sleep( init_timeout) => {
976+ return Err ( WorkerQuitReason :: fatal(
977+ LocalSessionWorkerError :: InitTimeout ( init_timeout) ,
978+ "waiting for initialize request" ,
979+ ) ) ;
980+ }
981+ } ;
969982 let SessionEvent :: InitializeRequest { request, responder } = evt else {
970983 return Err ( WorkerQuitReason :: fatal (
971984 LocalSessionWorkerError :: UnexpectedEvent ( evt) ,
@@ -1122,13 +1135,18 @@ pub struct SessionConfig {
11221135 /// resume requests. After this duration, completed entries are evicted
11231136 /// and resume will return an error. Default is 60 seconds.
11241137 pub completed_cache_ttl : Duration ,
1138+ /// Maximum duration to wait for the `initialize` request after session
1139+ /// creation. If not received within this window, the session is
1140+ /// terminated. Default is 60 seconds. Set to `None` to disable.
1141+ pub init_timeout : Option < Duration > ,
11251142}
11261143
11271144impl SessionConfig {
11281145 pub const DEFAULT_CHANNEL_CAPACITY : usize = 16 ;
11291146 pub const DEFAULT_KEEP_ALIVE : Duration = Duration :: from_secs ( 300 ) ;
11301147 pub const DEFAULT_SSE_RETRY : Duration = Duration :: from_secs ( 3 ) ;
11311148 pub const DEFAULT_COMPLETED_CACHE_TTL : Duration = Duration :: from_secs ( 60 ) ;
1149+ pub const DEFAULT_INIT_TIMEOUT : Duration = Duration :: from_secs ( 60 ) ;
11321150}
11331151
11341152impl Default for SessionConfig {
@@ -1138,6 +1156,7 @@ impl Default for SessionConfig {
11381156 keep_alive : Some ( Self :: DEFAULT_KEEP_ALIVE ) ,
11391157 sse_retry : Some ( Self :: DEFAULT_SSE_RETRY ) ,
11401158 completed_cache_ttl : Self :: DEFAULT_COMPLETED_CACHE_TTL ,
1159+ init_timeout : Some ( Self :: DEFAULT_INIT_TIMEOUT ) ,
11411160 }
11421161 }
11431162}
0 commit comments