@@ -771,7 +771,7 @@ - (void)_handleResubscriptionNeeded
771
771
[self _changeState: MTRDeviceStateUnknown];
772
772
}
773
773
774
- - (void )_handleSubscriptionReset
774
+ - (void )_handleSubscriptionReset : ( NSNumber * _Nullable) retryDelay
775
775
{
776
776
std::lock_guard lock (_lock);
777
777
// if there is no delegate then also do not retry
@@ -790,17 +790,29 @@ - (void)_handleSubscriptionReset
790
790
791
791
self.reattemptingSubscription = YES ;
792
792
793
+ NSTimeInterval secondsToWait;
793
794
if (_lastSubscriptionAttemptWait < MTRDEVICE_SUBSCRIPTION_ATTEMPT_MIN_WAIT_SECONDS) {
794
795
_lastSubscriptionAttemptWait = MTRDEVICE_SUBSCRIPTION_ATTEMPT_MIN_WAIT_SECONDS;
796
+ secondsToWait = _lastSubscriptionAttemptWait;
797
+ } else if (retryDelay != nil ) {
798
+ // The device responded but is currently busy. Reset our backoff
799
+ // counter, so that we don't end up waiting for a long time if the next
800
+ // attempt fails for some reason, and retry after whatever time period
801
+ // the device told us to use.
802
+ _lastSubscriptionAttemptWait = 0 ;
803
+ secondsToWait = retryDelay.doubleValue ;
804
+ MTR_LOG_INFO (" %@ resetting resubscribe attempt counter, and delaying by the server-provided delay: %f" ,
805
+ self, secondsToWait);
795
806
} else {
796
807
_lastSubscriptionAttemptWait *= 2 ;
797
808
if (_lastSubscriptionAttemptWait > MTRDEVICE_SUBSCRIPTION_ATTEMPT_MAX_WAIT_SECONDS) {
798
809
_lastSubscriptionAttemptWait = MTRDEVICE_SUBSCRIPTION_ATTEMPT_MAX_WAIT_SECONDS;
799
810
}
811
+ secondsToWait = _lastSubscriptionAttemptWait;
800
812
}
801
813
802
- MTR_LOG_DEFAULT (" %@ scheduling to reattempt subscription in %u seconds" , self, _lastSubscriptionAttemptWait );
803
- dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t ) (_lastSubscriptionAttemptWait * NSEC_PER_SEC)), self.queue , ^{
814
+ MTR_LOG_DEFAULT (" %@ scheduling to reattempt subscription in %f seconds" , self, secondsToWait );
815
+ dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t ) (secondsToWait * NSEC_PER_SEC)), self.queue , ^{
804
816
os_unfair_lock_lock (&self->_lock );
805
817
[self _reattemptSubscriptionNowIfNeeded ];
806
818
os_unfair_lock_unlock (&self->_lock );
@@ -1133,12 +1145,13 @@ - (void)_setupSubscription
1133
1145
[_deviceController
1134
1146
getSessionForNode: _nodeID.unsignedLongLongValue
1135
1147
completion: ^(chip: :Messaging: :ExchangeManager * _Nullable exchangeManager,
1136
- const chip: :Optional<chip: :SessionHandle> & session, NSError * _Nullable error) {
1148
+ const chip: :Optional<chip: :SessionHandle> & session, NSError * _Nullable error,
1149
+ NSNumber * _Nullable retryDelay) {
1137
1150
if (error != nil ) {
1138
1151
MTR_LOG_ERROR (" %@ getSessionForNode error %@" , self, error);
1139
1152
dispatch_async (self.queue , ^{
1140
1153
[self _handleSubscriptionError: error];
1141
- [self _handleSubscriptionReset ];
1154
+ [self _handleSubscriptionReset: retryDelay ];
1142
1155
});
1143
1156
return ;
1144
1157
}
@@ -1193,7 +1206,7 @@ - (void)_setupSubscription
1193
1206
1194
1207
dispatch_async (self.queue , ^{
1195
1208
// OnDone
1196
- [self _handleSubscriptionReset ];
1209
+ [self _handleSubscriptionReset: nil ];
1197
1210
});
1198
1211
os_unfair_lock_unlock (&self->_lock );
1199
1212
},
@@ -1300,7 +1313,7 @@ - (void)_setupSubscription
1300
1313
MTR_LOG_ERROR (" %@ SendAutoResubscribeRequest error %@" , self, error);
1301
1314
dispatch_async (self.queue , ^{
1302
1315
[self _handleSubscriptionError: error];
1303
- [self _handleSubscriptionReset ];
1316
+ [self _handleSubscriptionReset: nil ];
1304
1317
});
1305
1318
1306
1319
return ;
0 commit comments