Skip to content

Commit

Permalink
refactor(subscribe): wait for subscribe cancellation before other sub…
Browse files Browse the repository at this point in the history
…scribe actions
  • Loading branch information
parfeon committed Jun 26, 2024
1 parent 8561b9d commit 74c7af1
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 501 deletions.
9 changes: 6 additions & 3 deletions PubNub/Core/PubNub+Core.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ @interface PubNub () <PN_CORE_PROTOCOLS>

#pragma mark - Properties

// Handler which will be called when subscribe request will be cancelled.
@property(strong, nullable, nonatomic) dispatch_block_t subscribeCancellationHandler;
/// Resources access lock.
@property(strong, nonatomic) PNLock *lock;
#ifndef PUBNUB_DISABLE_LOGGER
Expand Down Expand Up @@ -318,7 +320,7 @@ - (void)copyWithConfiguration:(PNConfiguration *)configuration

if ([self.subscriberManager allObjects].count) {
// Stop any interactions on subscription loop.
[self cancelSubscribeOperations];
[self cancelSubscribeOperationsWithCompletion:nil];

BOOL uuidChanged = ![configuration.userID isEqualToString:self.configuration.userID];
BOOL authKeyChanged = ((self.configuration.authKey && !configuration.authKey) ||
Expand Down Expand Up @@ -402,8 +404,9 @@ - (void)prepareReachability {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
[weakSelf.reachability stopServicePing];
[weakSelf cancelSubscribeOperations];
[weakSelf.subscriberManager restoreSubscriptionCycleIfRequiredWithCompletion:nil];
[weakSelf cancelSubscribeOperationsWithCompletion:^{
[weakSelf.subscriberManager restoreSubscriptionCycleIfRequiredWithCompletion:nil];
}];
#pragma clang diagnostic pop
}
}];
Expand Down
3 changes: 3 additions & 0 deletions PubNub/Core/PubNub+CorePrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ typedef void(^PNParsedRequestCompletionBlock)(PNTransportRequest *,

#pragma mark - Properties

// Handler which will be called when subscribe request will be cancelled.
@property(strong, nullable, nonatomic) dispatch_block_t subscribeCancellationHandler;

/// Recent client state (whether it was connected or not).
@property (nonatomic, readonly, assign) PNStatusCategory recentClientStatus;

Expand Down
15 changes: 8 additions & 7 deletions PubNub/Core/PubNub+Presence.m
Original file line number Diff line number Diff line change
Expand Up @@ -412,13 +412,14 @@ - (void)setConnected:(BOOL)connected
[self heartbeatWithCompletion:block];
[self.heartbeatManager startHeartbeatIfRequired];
} else {
[self cancelSubscribeOperations];
[self.subscriberManager unsubscribeFromChannels:presenceChannels
groups:presenceChannelGroups
withQueryParameters:nil
listenersNotification:NO
completion:^(PNSubscribeStatus *status) {
if (block) block((id)status);
[self cancelSubscribeOperationsWithCompletion:^{
[self.subscriberManager unsubscribeFromChannels:presenceChannels
groups:presenceChannelGroups
withQueryParameters:nil
listenersNotification:NO
completion:^(PNSubscribeStatus *status) {
if (block) block((id)status);
}];
}];
}
} else {
Expand Down
54 changes: 42 additions & 12 deletions PubNub/Core/PubNub+Subscribe.m
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,9 @@ - (void)setFilterExpression:(NSString *)filterExpression {
#pragma mark - Subscription

- (void)subscribeWithRequest:(PNSubscribeRequest *)request {
[self cancelSubscribeOperations];
[self.subscriberManager subscribeWithRequest:request];
[self cancelSubscribeOperationsWithCompletion:^{
[self.subscriberManager subscribeWithRequest:request];
}];
}

- (void)subscribeWithRequest:(PNSubscribeRequest *)userRequest completion:(PNSubscriberCompletionBlock)handleBlock {
Expand All @@ -221,8 +222,14 @@ - (void)subscribeWithRequest:(PNSubscribeRequest *)userRequest completion:(PNSub
PNStrongify(self);

result.status.initialSubscription = [userRequest.timetoken isEqualToNumber:@0];

[self callBlock:block status:YES withResult:nil andStatus:result.status];
[self.lock writeAccessWithBlock:^{
if (self.subscribeCancellationHandler) {
self.subscribeCancellationHandler();
self.subscribeCancellationHandler = nil;
}

[self callBlock:block status:YES withResult:nil andStatus:result.status];
}];
};

[self performRequest:userRequest withParser:responseParser completion:handler];
Expand Down Expand Up @@ -316,8 +323,9 @@ - (void)subscribeToPresenceChannels:(NSArray<NSString *> *)channels withQueryPar
- (void)unsubscribeWithRequest:(PNPresenceLeaveRequest *)request {
if (request.channels.count == 0 && request.channelGroups.count == 0) return;

[self cancelSubscribeOperations];
[self.subscriberManager unsubscribeWithRequest:request completion:nil];
[self cancelSubscribeOperationsWithCompletion:^{
[self.subscriberManager unsubscribeWithRequest:request completion:nil];
}];
}

- (void)unsubscribeWithRequest:(PNPresenceLeaveRequest *)userRequest
Expand Down Expand Up @@ -367,8 +375,9 @@ - (void)unsubscribeFromChannels:(NSArray<NSString *> *)channels
request.observePresence = shouldObservePresence;

if (request.channels.count || request.channelGroups.count) {
[self cancelSubscribeOperations];
[self.subscriberManager unsubscribeWithRequest:request completion:block];
[self cancelSubscribeOperationsWithCompletion:^{
[self.subscriberManager unsubscribeWithRequest:request completion:block];
}];
} else if (block) {
pn_dispatch_async(self.callbackQueue, ^{
block(nil);
Expand Down Expand Up @@ -396,18 +405,39 @@ - (void)unsubscribeFromAllWithCompletion:(PNStatusBlock)block {
}

- (void)unsubscribeFromAllWithQueryParameters:(NSDictionary *)queryParameters completion:(PNStatusBlock)block {
[self cancelSubscribeOperations];
[self.subscriberManager unsubscribeFromAllWithQueryParameters:queryParameters completion:block];
[self cancelSubscribeOperationsWithCompletion:^{
[self.subscriberManager unsubscribeFromAllWithQueryParameters:queryParameters completion:block];
}];
}


#pragma mark - Misc

- (void)cancelSubscribeOperations {
- (void)cancelSubscribeOperationsWithCompletion:(dispatch_block_t)block {
[self.subscriptionNetwork requestsWithBlock:^(NSArray<PNTransportRequest *> *requests) {
BOOL hasSubscribeRequests = NO;

for(PNTransportRequest *request in requests) {
if ([request.path hasPrefix:kPNSubscribeAPIPrefix]) request.cancel();
if (!hasSubscribeRequests && [request.path hasPrefix:kPNSubscribeAPIPrefix]) {
hasSubscribeRequests = YES;
break;
}
}

dispatch_block_t cancelRequests = ^{
for(PNTransportRequest *request in requests) {
if ([request.path hasPrefix:kPNSubscribeAPIPrefix]) request.cancel();
}
};

if (hasSubscribeRequests) {
if (block) {
[self.lock writeAccessWithBlock:^{
self.subscribeCancellationHandler = [block copy];
cancelRequests();
}];
} else cancelRequests();
} else if (block) block();
}];
}

Expand Down
4 changes: 3 additions & 1 deletion PubNub/Core/PubNub+SubscribePrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Misc

/// Cancel any active long-polling subscribe operations scheduled for processing.
- (void)cancelSubscribeOperations;
///
/// - Parameter block: Subscribe request cancellatation handler block.
- (void)cancelSubscribeOperationsWithCompletion:(nullable dispatch_block_t)block;

#pragma mark -

Expand Down
9 changes: 5 additions & 4 deletions PubNub/Data/Managers/PNSubscriber.m
Original file line number Diff line number Diff line change
Expand Up @@ -839,10 +839,11 @@ - (void)subscribe:(BOOL)initialSubscribe
[self updateStateTo:PNDisconnectedSubscriberState
withStatus:(PNSubscribeStatus *)status
completion:^(PNStatusCategory category) {
[self.client cancelSubscribeOperations];
[status updateCategory:category];

[self.client callBlock:nil status:YES withResult:nil andStatus:status];
[self.client cancelSubscribeOperationsWithCompletion:^{
[status updateCategory:category];

[self.client callBlock:nil status:YES withResult:nil andStatus:status];
}];
}];
}
#pragma clang diagnostic pop
Expand Down
8 changes: 4 additions & 4 deletions Tests/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
PODS:
- Cucumberish (1.4.0)
- OCMock (3.6)
- PubNub (5.4.1):
- PubNub/Core (= 5.4.1)
- PubNub/Core (5.4.1)
- PubNub (5.5.0):
- PubNub/Core (= 5.5.0)
- PubNub/Core (5.5.0)
- YAHTTPVCR (1.5.0)

DEPENDENCIES:
Expand Down Expand Up @@ -32,7 +32,7 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
Cucumberish: 6cbd0c1f50306b369acebfe7d9f514c9c287d26c
OCMock: 5ea90566be239f179ba766fd9fbae5885040b992
PubNub: b9d51645534909e74c3407857049732f817d3a8e
PubNub: 17b22578c960a206863289c3662d0ccc803c71f7
YAHTTPVCR: cb7a710d4289ee9b038fd708d2fb8df4e6521bc0

PODFILE CHECKSUM: fb38a10e9ab7ec6c9e4fe43e6a3b6ffc35154550
Expand Down
Loading

0 comments on commit 74c7af1

Please sign in to comment.