@@ -87,11 +87,27 @@ void SoundLevelMeter::setup() {
8787}
8888
8989void SoundLevelMeter::loop () {
90- std::lock_guard<std::mutex> lock (this ->defer_mutex_ );
9190 if (!this ->defer_queue_ .empty ()) {
92- auto &f = this ->defer_queue_ .front ();
93- f ();
94- this ->defer_queue_ .pop_front ();
91+ std::lock_guard<std::mutex> lock (this ->defer_mutex_ );
92+ // Process no more than 5 items per loop iteration.
93+ // When there are many sensors with short update intervals,
94+ // a large number of state updates (publish_state) may be queued.
95+ // Publishing state is a relatively expensive operation, so calling
96+ // it more than 10–20 times per iteration could trigger a warning
97+ // that the component is taking too long to operate. Therefore, we
98+ // limit the number of updates per iteration. The loop runs approximately
99+ // 100 times per second, so any remaining items will be processed
100+ // in the next iteration. Processing only one item per iteration is too
101+ // restrictive, as in extreme cases with many updates - say,
102+ // 100 per second - we might hit performance limits. Thus, we set a maximum
103+ // of 5 items per iteration, allowing up to 500 sensor updates per second
104+ // in theory, which should be more than sufficient for most scenarios.
105+ uint32_t max_items = std::min (this ->defer_queue_ .size (), (size_t ) 5 );
106+ for (int i = 0 ; i < max_items; i++) {
107+ auto &f = this ->defer_queue_ .front ();
108+ f ();
109+ this ->defer_queue_ .pop_front ();
110+ }
95111 }
96112}
97113
0 commit comments