From 9c0cb3a334de553ba8f4e8079b49f0301c6f62be Mon Sep 17 00:00:00 2001 From: Stanislav Hejny Date: Wed, 16 Jul 2025 18:04:09 +0100 Subject: [PATCH] refactor: update backpressure logic to handle availability correctly Co-authored-by: aider (openrouter/openai/o3-mini-high) --- amqp/adapter/backpressure_handler.py | 45 +++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/amqp/adapter/backpressure_handler.py b/amqp/adapter/backpressure_handler.py index f566e52..1d52fc6 100644 --- a/amqp/adapter/backpressure_handler.py +++ b/amqp/adapter/backpressure_handler.py @@ -192,20 +192,32 @@ class BackpressureHandler: async def check_overload_condition(self): """ - Check if the current parallel executions exceed the limit (OVERLOAD) - or if the service has been idle for too long (IDLE). + Check if the current availability is too low (OVERLOAD) + or if the service has been idle for too long with high availability (IDLE). + + Note: current_availability represents available capacity, not used capacity. + - Low availability (close to 0) means OVERLOAD + - High availability (close to maximum) with no activity means IDLE """ current_time = time.time() last_event_delta = current_time - self.last_backpressure_event_time + + # If maximum is not set or invalid, use the highest seen value + if self.maximum_load <= 0 and self.current_load > 0: + self.maximum_load = self.current_load + elif self.current_load > self.maximum_load: + # Update maximum if we see a higher value + self.maximum_load = self.current_load + logging_info( - "Backpressure: Check conditions, current=%s, max=%s, last_activity=%s", + "Backpressure: Check conditions, current_availability=%s, max=%s, last_activity=%s", self.current_load, self.maximum_load, last_event_delta, ) - - # Check for OVERLOAD condition - if self.current_load >= round(0.8 * self.maximum_load): + + # Check for OVERLOAD condition - low availability (less than 20% of maximum) + if self.current_load <= round(0.2 * self.maximum_load): # Check if the last backpressure event was not an overload if self.last_backpressure_event != ScalingRequestAlert.OVERLOAD: # Trigger the overload event @@ -213,44 +225,43 @@ class BackpressureHandler: # update / reset time-window so that the OVERLOAD is not sent too often self.last_backpressure_event_time = current_time self.last_backpressure_event = ScalingRequestAlert.OVERLOAD - - # Check for IDLE condition - elif self.current_load == 0: + + # Check for IDLE condition - high availability (more than 80% of maximum) with no activity + elif self.current_load >= round(0.8 * self.maximum_load): idle_duration = self.config.backpressure.idle_duration # Check if service has been idle for longer than the configured duration if ( last_event_delta > idle_duration and self.last_backpressure_event == ScalingRequestAlert.IDLE ): - logging_info( "Backpressure: Service has been idle for %s seconds (threshold: %s seconds)", last_event_delta, idle_duration, ) - + # Trigger the idle event await self._handle_backpressure_idle_event() # update / reset time-window so that the IDLE is not sent too often self.last_backpressure_event_time = current_time else: - # Don't send IDLE right away when the usage drops to zero / below threshold, but wait for a while + # Don't send IDLE right away when the availability increases, but wait for a while self.last_backpressure_event = ScalingRequestAlert.IDLE - + # If neither OVERLOAD nor IDLE, and it's time for an update, send UPDATE event elif last_event_delta > self.config.backpressure.time_window: _scaling_request: ScaleRequestV1 = ScaleRequestV1( self.swarm_service_id, self.swarm_task_id, self.maximum_load, - self.maximum_load - self.current_load, + self.current_load, # Current availability is passed directly ScalingRequestAlert.UPDATE, ) # Address the message to any adapter capable of supporting BACKPRESSURE request await self.publish_backpressure_request(_scaling_request) self.last_backpressure_event_time = current_time self.last_backpressure_event = ScalingRequestAlert.UPDATE - + self.update_last_data_message_time() async def _backpressure_monitor(self): @@ -353,7 +364,7 @@ class BackpressureHandler: self.swarm_service_id, self.swarm_task_id, self.maximum_load, - self.maximum_load - self.current_load, + self.current_load, # Current availability is passed directly ScalingRequestAlert.OVERLOAD, ) # Address the message to any management service instance capable of supporting BACKPRESSURE request @@ -366,7 +377,7 @@ class BackpressureHandler: self.swarm_service_id, self.swarm_task_id, self.maximum_load, - self.maximum_load - self.current_load, + self.current_load, # Current availability is passed directly ScalingRequestAlert.IDLE, ) # Address the message to any adapter capable of supporting BACKPRESSURE request