@@ -139,6 +139,7 @@ def __init__(self, cfg: FDConfig, start_queue=True, use_async_llm=False):
139139
140140 self .is_paused = False # pause request generation
141141 self ._pause_cond = threading .Condition ()
142+ self ._rejecting_new_requests = False # blocks new requests during abort drain
142143
143144 self ._ctrl_output_queues = {}
144145 self ._ctrl_response_mailboxes = collections .defaultdict (collections .OrderedDict )
@@ -1106,7 +1107,7 @@ def _insert_zmq_task_to_scheduler(self):
11061107 trace_print (LoggingEventName .REQUEST_QUEUE_START , data ["request_id" ], data .get ("user" , "" ))
11071108 self .llm_logger .debug (f"Receive request from api server: { request } " )
11081109
1109- if self .is_paused :
1110+ if self .is_paused or self . _rejecting_new_requests :
11101111 self .llm_logger .warning (f"Engine is paused, drop request: { request } " )
11111112 self ._send_error_response (
11121113 request .request_id ,
@@ -1226,39 +1227,20 @@ def _control_pause(self, control_request: ControlRequest):
12261227 if self .is_paused :
12271228 self .llm_logger .info ("Engine is already paused, no need to pause again." )
12281229 return
1229- self .is_paused = True
1230+ self ._rejecting_new_requests = True
1231+ self .resource_manager .log_status ()
12301232
1231- self .llm_logger .info ("Abort running requests." )
1233+ # Scheduling loop picks them up via _trigger_abort when they enter resource_manager
1234+ all_req_ids = list (set (self .resource_manager .requests .keys ()) | set (self .scheduler .requests .keys ()))
1235+ self .llm_logger .info (f"Pause: aborting { len (all_req_ids )} total requests." )
1236+ if all_req_ids :
1237+ self .resource_manager .add_abort_req_ids (all_req_ids )
1238+ self ._wait_inflight_drained ()
12321239
1233- self .resource_manager .log_status ()
1234- # preempted all running reqs. preempted reqs will be append to ResourceManager.waiting queue
1235- timeout , count = 60 , 0
1236- while self .engine_worker_queue .exist_tasks ():
1237- time .sleep (0.001 )
1238- count += 1
1239- if count >= timeout * 1000 :
1240- break
1241- if count >= timeout * 1000 :
1242- error_msg = f"Emptying engine worker queue timed out after { timeout } seconds, worker may hanged!"
1243- self .llm_logger .error (error_msg )
1244- raise Exception (error_msg )
1245- running_reqs = self .resource_manager .preempted_all ()
1246- if len (running_reqs ) > 0 :
1247- self .llm_logger .info (f"Total { len (running_reqs )} requests need to be aborted." )
1248- self .resource_manager .get_real_bsz ()
1249- self .engine_worker_queue .put_tasks ((running_reqs , self .resource_manager .real_bsz ))
1250- self .resource_manager .wait_worker_inflight_requests_finish (timeout = 60 )
1251- # self.engine_worker_queue.clear_data()
1252- self .token_processor .clear_data ()
1240+ with self ._pause_cond :
1241+ self .is_paused = True
12531242 self .resource_manager .log_status ()
12541243
1255- # abort inflight requests to user
1256- inflight_requests = self .scheduler .get_inflight_requests ()
1257- self .llm_logger .info (f"Abort inflight requests (total { len (inflight_requests )} )." )
1258- for req in inflight_requests :
1259- self ._send_error_response (req .request_id , "Request is aborted since engine is paused." )
1260- self .scheduler .reset ()
1261-
12621244 # pause cache transfer
12631245 if self .cfg .cache_config .num_cpu_blocks > 0 or self .cfg .cache_config .kvcache_storage_backend :
12641246 self .llm_logger .info ("Start to pause cache transfer." )
@@ -1278,6 +1260,21 @@ def _control_pause(self, control_request: ControlRequest):
12781260 self .llm_logger .info ("Successfully paused request generation." )
12791261 return None
12801262
1263+ def _wait_inflight_drained (self ):
1264+ """
1265+ Wait until resource_manager.requests is completely empty.
1266+ No timeout — abort pipeline will complete. Aligned with SGLang's poll-until-drained.
1267+ """
1268+ start_time = time .time ()
1269+ while (
1270+ self .resource_manager .requests
1271+ or self .scheduler .requests
1272+ or self .resource_manager .waiting_abort_req_id_set
1273+ or self .resource_manager .to_be_aborted_req_id_set
1274+ ):
1275+ time .sleep (0.005 )
1276+ self .llm_logger .info (f"All inflight requests drained, take time: { time .time () - start_time :.3f} seconds" )
1277+
12811278 def _control_resume (self , control_request : ControlRequest ) -> Optional [dict ]:
12821279 """Control function for resuming request generation.
12831280
@@ -1293,6 +1290,7 @@ def _control_resume(self, control_request: ControlRequest) -> Optional[dict]:
12931290 self .llm_logger .info ("Engine is not paused, no need to resume." )
12941291 return None
12951292 self .is_paused = False
1293+ self ._rejecting_new_requests = False
12961294 self ._pause_cond .notify_all ()
12971295
12981296 # resume cache transfer
0 commit comments