diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 12ba156e346056..4e29b0e5e3d3a3 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -332,6 +332,7 @@ @interface MTRDevice_Concrete () @property (nonatomic) NSDate * estimatedStartTimeFromGeneralDiagnosticsUpTime; @property (nonatomic) NSDate * lastDeviceBecameActiveCallbackTime; +@property (nonatomic) BOOL throttlingDeviceBecameActiveCallbacks; /** * If currentReadClient is non-null, that means that we successfully @@ -472,6 +473,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle _persistedClusters = [NSMutableSet set]; _highestObservedEventNumber = nil; _matterCPPObjectsHolder = [[MTRDeviceMatterCPPObjectsHolder alloc] init]; + _throttlingDeviceBecameActiveCallbacks = NO; // If there is a data store, make sure we have an observer to monitor system clock changes, so // NSDate-based write coalescing could be reset and not get into a bad state. @@ -866,6 +868,7 @@ - (void)_setDSTOffsets:(NSArray // subscription intervals are in seconds #define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN (10 * 60) // 10 minutes (for now) #define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX (60 * 60) // 60 minutes +#define MTR_DEVICE_MIN_SECONDS_BETWEEN_DEVICE_BECAME_ACTIVE_CALLBACKS (1 * 60) // 1 minute (for now) - (BOOL)_subscriptionsAllowed { @@ -1640,7 +1643,7 @@ - (void)_handleUnsolicitedMessageFromPublisher BOOL shouldCallDelegate = NO; if (self.lastDeviceBecameActiveCallbackTime) { NSTimeInterval intervalSinceLastCallback = -[self.lastDeviceBecameActiveCallbackTime timeIntervalSinceNow]; - if (intervalSinceLastCallback > MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN) { + if (intervalSinceLastCallback > MTR_DEVICE_MIN_SECONDS_BETWEEN_DEVICE_BECAME_ACTIVE_CALLBACKS) { shouldCallDelegate = YES; } } else { @@ -1654,6 +1657,10 @@ - (void)_handleUnsolicitedMessageFromPublisher } }]; self.lastDeviceBecameActiveCallbackTime = [NSDate now]; + self.throttlingDeviceBecameActiveCallbacks = NO; + } else if (!self.throttlingDeviceBecameActiveCallbacks) { + MTR_LOG("%@ throttling deviceBecameActive callbacks because report came in too soon after %@", self, self.lastDeviceBecameActiveCallbackTime); + self.throttlingDeviceBecameActiveCallbacks = YES; } // in case this is called during exponential back off of subscription