Skip to content

Commit 1348a8a

Browse files
[Darwin] MTRDevice should throttle deviceBecameActive callbacks (#37436)
* [Darwin] MTRDevice should throttle deviceBecameActive callbacks * * Use a slightly shorter interval with its own define for deviceBecameActive throttling. * Log when we start throttling deviceBecameActive callbacks. --------- Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent ee6341e commit 1348a8a

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

src/darwin/Framework/CHIP/MTRDevice_Concrete.mm

+27-5
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ @interface MTRDevice_Concrete ()
331331

332332
@property (nonatomic) NSDate * estimatedStartTimeFromGeneralDiagnosticsUpTime;
333333

334+
@property (nonatomic) NSDate * lastDeviceBecameActiveCallbackTime;
335+
@property (nonatomic) BOOL throttlingDeviceBecameActiveCallbacks;
336+
334337
/**
335338
* If currentReadClient is non-null, that means that we successfully
336339
* called SendAutoResubscribeRequest on the ReadClient and have not yet gotten
@@ -470,6 +473,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle
470473
_persistedClusters = [NSMutableSet set];
471474
_highestObservedEventNumber = nil;
472475
_matterCPPObjectsHolder = [[MTRDeviceMatterCPPObjectsHolder alloc] init];
476+
_throttlingDeviceBecameActiveCallbacks = NO;
473477

474478
// If there is a data store, make sure we have an observer to monitor system clock changes, so
475479
// NSDate-based write coalescing could be reset and not get into a bad state.
@@ -864,6 +868,7 @@ - (void)_setDSTOffsets:(NSArray<MTRTimeSynchronizationClusterDSTOffsetStruct *>
864868
// subscription intervals are in seconds
865869
#define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN (10 * 60) // 10 minutes (for now)
866870
#define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX (60 * 60) // 60 minutes
871+
#define MTR_DEVICE_MIN_SECONDS_BETWEEN_DEVICE_BECAME_ACTIVE_CALLBACKS (1 * 60) // 1 minute (for now)
867872

868873
- (BOOL)_subscriptionsAllowed
869874
{
@@ -1634,12 +1639,29 @@ - (void)_handleUnsolicitedMessageFromPublisher
16341639

16351640
[self _changeState:MTRDeviceStateReachable];
16361641

1637-
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
1638-
if ([delegate respondsToSelector:@selector(deviceBecameActive:)]) {
1639-
[delegate deviceBecameActive:self];
1642+
// Given the framework requests a minimum subscription keep alive time of devices, this callback is not expected to happen more often than that
1643+
BOOL shouldCallDelegate = NO;
1644+
if (self.lastDeviceBecameActiveCallbackTime) {
1645+
NSTimeInterval intervalSinceLastCallback = -[self.lastDeviceBecameActiveCallbackTime timeIntervalSinceNow];
1646+
if (intervalSinceLastCallback > MTR_DEVICE_MIN_SECONDS_BETWEEN_DEVICE_BECAME_ACTIVE_CALLBACKS) {
1647+
shouldCallDelegate = YES;
16401648
}
1641-
}];
1642-
[self _notifyDelegateOfPrivateInternalPropertiesChanges];
1649+
} else {
1650+
shouldCallDelegate = YES;
1651+
}
1652+
1653+
if (shouldCallDelegate) {
1654+
[self _callDelegatesWithBlock:^(id<MTRDeviceDelegate> delegate) {
1655+
if ([delegate respondsToSelector:@selector(deviceBecameActive:)]) {
1656+
[delegate deviceBecameActive:self];
1657+
}
1658+
}];
1659+
self.lastDeviceBecameActiveCallbackTime = [NSDate now];
1660+
self.throttlingDeviceBecameActiveCallbacks = NO;
1661+
} else if (!self.throttlingDeviceBecameActiveCallbacks) {
1662+
MTR_LOG("%@ throttling deviceBecameActive callbacks because report came in too soon after %@", self, self.lastDeviceBecameActiveCallbackTime);
1663+
self.throttlingDeviceBecameActiveCallbacks = YES;
1664+
}
16431665

16441666
// in case this is called during exponential back off of subscription
16451667
// reestablishment, this starts the attempt right away

0 commit comments

Comments
 (0)