diff --git a/litellm/integrations/SlackAlerting/slack_alerting.py b/litellm/integrations/SlackAlerting/slack_alerting.py index 013cef74805..34a53a8be33 100644 --- a/litellm/integrations/SlackAlerting/slack_alerting.py +++ b/litellm/integrations/SlackAlerting/slack_alerting.py @@ -115,8 +115,9 @@ class SlackAlerting(CustomBatchLogger): ): if alerting is not None: self.alerting = alerting - asyncio.create_task(self.periodic_flush()) - self.periodic_started = True + if not self.periodic_started: + asyncio.create_task(self.periodic_flush()) + self.periodic_started = True if alerting_threshold is not None: self.alerting_threshold = alerting_threshold if alert_types is not None: diff --git a/tests/test_litellm/integrations/SlackAlerting/test_slack_alerting.py b/tests/test_litellm/integrations/SlackAlerting/test_slack_alerting.py index 128a88a0f12..8d8f88a30af 100644 --- a/tests/test_litellm/integrations/SlackAlerting/test_slack_alerting.py +++ b/tests/test_litellm/integrations/SlackAlerting/test_slack_alerting.py @@ -173,6 +173,21 @@ class TestSlackAlerting(unittest.TestCase): self.slack_alerting.update_values(alerting_args={"slack_alerting": "True"}) assert self.slack_alerting.periodic_started == True + # Repeated calls to update_values should not spawn additional periodic_flush tasks + @patch("asyncio.create_task") + def test_update_values_does_not_leak_periodic_tasks(self, mock_create_task): + mock_create_task.return_value = AsyncMock() + + self.slack_alerting.update_values(alerting=["slack"]) + assert self.slack_alerting.periodic_started == True + assert mock_create_task.call_count == 1 + + # Simulate repeated calls from add_deployment scheduler (runs every 30s) + self.slack_alerting.update_values(alerting=["slack"]) + self.slack_alerting.update_values(alerting=["slack"]) + self.slack_alerting.update_values(alerting_args={"slack_alerting": "True"}) + assert mock_create_task.call_count == 1 + @patch("litellm.integrations.SlackAlerting.slack_alerting.datetime") def test_alert_type_in_formatted_message(self, mock_datetime): # Setup mocks