From 0005de4ed1a315383ac5f4d97ee76aa41010aabe Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sun, 1 Nov 2026 22:14:56 +0100 Subject: [PATCH] Disable Sentry sampling at a zero interval --- tests/test_executor.py | 14 ++++++ threadmill/executor.py | 49 ++++++++++---------- threadmill/management/commands/threadmill.py | 2 +- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/tests/test_executor.py b/tests/test_executor.py index 9e3646d..d4a42d7 100644 --- a/tests/test_executor.py +++ b/tests/test_executor.py @@ -820,6 +820,20 @@ def test_report_metrics__samples_pool_and_queue_counts(self, monkeypatch): ] assert shutdown_requested.timeouts == [7.0] + def test_report_metrics__zero_interval_disables_sampling(self, monkeypatch): + """Skip sampling when the interval is zero.""" + executor = TaskExecutor( + backend=StubQueueStatsBackend(BackendTelemetry(queues={})), + queues=("default",), + sample_interval=datetime.timedelta(0), + ) + sentry_metrics = StubSentryMetrics() + monkeypatch.setattr(executor_module, "sentry_metrics", sentry_metrics) + + executor.report_metrics() + + assert sentry_metrics.gauges == [] + class TestWorkerProcess: """Tests for the WorkerProcess class.""" diff --git a/threadmill/executor.py b/threadmill/executor.py index 254dff3..53472a9 100644 --- a/threadmill/executor.py +++ b/threadmill/executor.py @@ -246,30 +246,31 @@ def maintain_worker_pool(self) -> None: def report_metrics(self) -> None: """Sample queue depth and worker counts into Sentry until shutdown.""" - while not self.shutdown_requested.is_set(): - sentry_metrics.gauge( - "threadmill.worker.count", - self.process_count, - attributes={"pool": "process"}, - ) - sentry_metrics.gauge( - "threadmill.worker.count", - self.process_count * self.thread_count, - attributes={"pool": "thread"}, - ) - telemetry = asyncio.run(self.backend.queue_stats()) - for queue_name, stats in telemetry.queues.items(): - for status, depth in ( - ("ready", stats.counts.ready), - ("running", stats.counts.running), - ("deferred", stats.counts.deferred), - ): - sentry_metrics.gauge( - "threadmill.queue.depth", - depth, - attributes={"queue": queue_name, "status": status}, - ) - self.shutdown_requested.wait(self.sample_interval.total_seconds()) + if self.sample_interval > datetime.timedelta(0): + while not self.shutdown_requested.is_set(): + sentry_metrics.gauge( + "threadmill.worker.count", + self.process_count, + attributes={"pool": "process"}, + ) + sentry_metrics.gauge( + "threadmill.worker.count", + self.process_count * self.thread_count, + attributes={"pool": "thread"}, + ) + telemetry = asyncio.run(self.backend.queue_stats()) + for queue_name, stats in telemetry.queues.items(): + for status, depth in ( + ("ready", stats.counts.ready), + ("running", stats.counts.running), + ("deferred", stats.counts.deferred), + ): + sentry_metrics.gauge( + "threadmill.queue.depth", + depth, + attributes={"queue": queue_name, "status": status}, + ) + self.shutdown_requested.wait(self.sample_interval.total_seconds()) class WorkerProcess(multiprocessing.Process): diff --git a/threadmill/management/commands/threadmill.py b/threadmill/management/commands/threadmill.py index 29c492f..fc6803b 100644 --- a/threadmill/management/commands/threadmill.py +++ b/threadmill/management/commands/threadmill.py @@ -114,7 +114,7 @@ def add_arguments(self, parser): default=datetime.timedelta(seconds=30), help=( "Interval between queue depth and worker count samples in seconds." - " Defaults to 30." + " Defaults to 30. Set to 0 to disable sampling." ), ) parser.add_argument(