feat/58 - improve Backpressure algorithm

This commit is contained in:
Stanislav Hejny
2025-07-15 16:40:02 +01:00
parent 7d4e358ce5
commit 7cd2960fda
6 changed files with 230 additions and 247 deletions
+6 -6
View File
@@ -124,10 +124,10 @@ class DataMessageHandler:
:return: DataResponse
"""
# Increment the counter for parallel executions and check resource availability
self.backpressure_handler.increase_parallel_executions()
self.backpressure_handler.increase_current_load()
await self.backpressure_handler.check_overload_condition()
logging_info(
f"PARALLEL: Current Capacity [{self.backpressure_handler.current_parallel_executions}] of [{self.backpressure_handler.parallel_workers}]"
f"PARALLEL: Current Capacity [{self.backpressure_handler.current_load}] of [{self.backpressure_handler.maximum_load}]"
)
if message.reply_to:
self.reply_to = message.reply_to
@@ -155,7 +155,7 @@ class DataMessageHandler:
except Exception as e:
logging_error(f"Request handler: {e}")
self.backpressure_handler.decrease_parallel_executions()
self.backpressure_handler.decrease_current_load()
await self.backpressure_handler.check_overload_condition()
async def reconstitute_data_message(
@@ -208,12 +208,12 @@ class DataMessageHandler:
# map_as_string(amq_message.trace_info()), context_with_span, context)
def record_duration(self, start, delivery_tag):
global last_data_message_time
last_data_message_time = time.time()
global last_backpressure_event_time
last_backpressure_event_time = time.time()
logging_info(
"######[%s] Done, single ACK: %sms.",
delivery_tag,
last_data_message_time - start,
last_backpressure_event_time - start,
)
async def send_reply(self, reply_to: str, response: DataResponse):
+12 -9
View File
@@ -83,24 +83,27 @@ class AMQService:
logging.info("***********************************************")
self.loop.run_forever()
def backpressure(self, current: int, maximum: int = -1):
def backpressure(self, current_availability: int, maximum: int = -1):
"""
Send Backpressure event to the Management Service. The Backpressure logic determines the type of the event
based on the current and maximum values.
- OVERLOAD event is triggered immediately when the current value exceeds the maximum threshold, which is
based on the current_availability and maximum values.
- OVERLOAD event is triggered immediately when the current_availability value exceeds the maximum threshold, which is
typically set to 80% of the maximum value.
- IDLE event is triggered when the current value drops below 20% of the maximum value and remains there for
- IDLE event is triggered when the current_availability value drops below 20% of the maximum value and remains there for
a IDLE_WINDOW period of time (see BackpressureHandler).
- UPDATE event is sent if neither OVERLOAD nor IDLE conditions are met, indicating that the backpressure is
within acceptable limits.
:param current: Current value of the backpressure metric.
:param maximum: Maximum value of the backpressure metric. If undefined or set to lt 0, the maximum is set
according to the configuration value 'cm.backpressure.threshold'.
:param current_availability: Currently available caopacity.
:param maximum: Maximum value of the backpressure metric. If undefined or set to lt 0 (e.g. -1),
the maximum is than hgdetermined from max value of current_availability seen over the time.
"""
if self.backpressure_handler is not None:
if maximum < 0:
maximum = self.amq_configuration.backpressure.threshold_threads
self.backpressure_handler.update_backpressure_value(current, maximum)
maximum = self.amq_configuration.backpressure.threshold_load
asyncio.run_coroutine_threadsafe(
self.backpressure_handler.update_backpressure_value(current_availability, maximum),
loop=self.backpressure_handler.loop,
)
def rpc(self, service_name: str, fq_method_name: str, **kwargs) -> Future:
"""