Skip to content

Commit

Permalink
Updated presence map according to the new specs RTP17*.
Browse files Browse the repository at this point in the history
Co-authored-by: ikbalkaya <[email protected]>
  • Loading branch information
maratal and ikbalkaya committed May 15, 2023
1 parent 27f154c commit ebc91c2
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 17 deletions.
22 changes: 10 additions & 12 deletions Source/ARTPresenceMap.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ @interface ARTPresenceMap () {
ARTPresenceSyncState _syncState;
ARTEventEmitter<ARTEvent * /*ARTSyncState*/, id> *_syncEventEmitter;
NSMutableDictionary<NSString *, ARTPresenceMessage *> *_members;
NSMutableSet<ARTPresenceMessage *> *_localMembers;
NSMutableDictionary<NSString *, ARTPresenceMessage *> *_localMembers; // RTP17h
}

@end
Expand All @@ -64,7 +64,7 @@ - (instancetype)initWithQueue:(_Nonnull dispatch_queue_t)queue logger:(ARTIntern
return _members;
}

- (NSMutableSet<ARTPresenceMessage *> *)localMembers {
- (NSDictionary<NSString *, ARTPresenceMessage *> *)localMembers {
return _localMembers;
}

Expand Down Expand Up @@ -102,7 +102,7 @@ - (void)internalAdd:(ARTPresenceMessage *)message withSessionId:(NSUInteger)sess
[_members setObject:message forKey:message.memberKey];
// Local member
if ([message.connectionId isEqualToString:self.delegate.connectionId]) {
[_localMembers addObject:message];
_localMembers[message.clientId] = message;
ARTLogDebug(_logger, @"local member %@ with action %@ has been added", message.memberKey, ARTPresenceActionToStr(message.action).uppercaseString);
}
}
Expand All @@ -113,7 +113,7 @@ - (void)internalRemove:(ARTPresenceMessage *)message {

- (void)internalRemove:(ARTPresenceMessage *)message force:(BOOL)force {
if ([message.connectionId isEqualToString:self.delegate.connectionId] && !message.isSynthesized) {
[_localMembers removeObject:message];
[_localMembers removeObjectForKey:message.clientId];
}

const BOOL syncInProgress = self.syncInProgress;
Expand Down Expand Up @@ -150,20 +150,18 @@ - (void)leaveMembersNotPresentInSync {
}
}

- (void)reenterLocalMembersMissingFromSync {
ARTLogDebug(_logger, @"%p reentering local members missed from sync (syncSessionId=%lu)", self, (unsigned long)_syncSessionId);
NSSet *filteredLocalMembers = [_localMembers filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"syncSessionId != %lu", (unsigned long)_syncSessionId]];
for (ARTPresenceMessage *localMember in filteredLocalMembers) {
- (void)reenterLocalMembers {
ARTLogDebug(_logger, @"%p reentering local members", self);
for (ARTPresenceMessage *localMember in [_localMembers allValues]) {
ARTPresenceMessage *reenter = [localMember copy];
[self internalRemove:localMember];
[self.delegate map:self shouldReenterLocalMember:reenter];
}
[self cleanUpAbsentMembers];
}

- (void)reset {
_members = [NSMutableDictionary dictionary];
_localMembers = [NSMutableSet set];
_members = [NSMutableDictionary new];
_localMembers = [NSMutableDictionary new];
}

- (void)startSync {
Expand All @@ -178,7 +176,7 @@ - (void)endSync {
[self cleanUpAbsentMembers];
[self leaveMembersNotPresentInSync];
_syncState = ARTPresenceSyncEnded;
[self reenterLocalMembersMissingFromSync];

[_syncEventEmitter emit:[ARTEvent newWithPresenceSyncState:ARTPresenceSyncEnded] with:[_members allValues]];
[_syncEventEmitter off];
ARTLogDebug(_logger, @"%p PresenceMap sync ended", self);
Expand Down
1 change: 1 addition & 0 deletions Source/ARTProtocolMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ - (NSString *)description {
[description appendFormat:@" flags.hasBacklog: %@,\n", NSStringFromBOOL(self.hasBacklog)];
[description appendFormat:@" flags.resumed: %@,\n", NSStringFromBOOL(self.resumed)];
[description appendFormat:@" messages: %@\n", self.messages];
[description appendFormat:@" presence: %@\n", self.presence];
[description appendFormat:@" params: %@\n", self.params];
[description appendFormat:@"}"];
return description;
Expand Down
18 changes: 13 additions & 5 deletions Source/ARTRealtimeChannel.m
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ - (void)setAttached:(ARTProtocolMessage *)message {
[_attachedEventEmitter emit:nil with:nil];

[self.presence sendPendingPresence];
[self.presenceMap reenterLocalMembers]; // RTP17f, RTP17g
}

- (void)setDetached:(ARTProtocolMessage *)message {
Expand Down Expand Up @@ -1232,11 +1233,18 @@ - (void)map:(ARTPresenceMap *)map didRemovedMemberNoLongerPresent:(ARTPresenceMe
}

- (void)map:(ARTPresenceMap *)map shouldReenterLocalMember:(ARTPresenceMessage *)presence {
[self.presence enterClient:presence.clientId data:presence.data callback:^(ARTErrorInfo *error) {
NSString *message = [NSString stringWithFormat:@"Re-entering member \"%@\" as failed with code %ld (%@)", presence.clientId, (long)error.code, error.message];
ARTErrorInfo *reenterError = [ARTErrorInfo createWithCode:ARTErrorUnableToAutomaticallyReEnterPresenceChannel message:message];
ARTChannelStateChange *stateChange = [[ARTChannelStateChange alloc] initWithCurrent:self.state_nosync previous:self.state_nosync event:ARTChannelEventUpdate reason:reenterError resumed:true];
[self emit:stateChange.event with:stateChange];
[self.presence reenterWithPresenceMessage:presence callback:^(ARTErrorInfo *error) {
if (error != nil) {
NSString *message = [NSString stringWithFormat:@"Re-entering member \"%@\" is failed with code %ld (%@)", presence.clientId, (long)error.code, error.message];
ARTErrorInfo *reenterError = [ARTErrorInfo createWithCode:ARTErrorUnableToAutomaticallyReEnterPresenceChannel message:message];
ARTLogError(self.logger, @"%@", reenterError);
ARTChannelStateChange *stateChange = [[ARTChannelStateChange alloc] initWithCurrent:self.state_nosync previous:self.state_nosync event:ARTChannelEventUpdate reason:reenterError resumed:true]; // RTP17e
[self emit:stateChange.event with:stateChange];
ARTLogWarn(self.logger, @"RT:%p C:%p (%@) Re-entering member \"%@\" is failed with code %ld (%@)", self->_realtime, self, self.name, presence.memberKey, (long)error.code, error.message);
}
else {
ARTLogDebug(self.logger, @"RT:%p C:%p (%@) re-entered local member \"%@\"", self->_realtime, self, self.name, presence.memberKey);
}
}];
ARTLogDebug(self.logger, @"RT:%p C:%p (%@) re-entering local member \"%@\"", _realtime, self, self.name, presence.memberKey);
}
Expand Down
38 changes: 38 additions & 0 deletions Source/ARTRealtimePresence.m
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,20 @@ - (void)enterClient:(NSString *)clientId data:(id)data callback:(ARTCallback)cb
});
}

- (void)reenterWithPresenceMessage:(ARTPresenceMessage *)message callback:(ARTCallback)cb {
if (cb) {
ARTCallback userCallback = cb;
cb = ^(ARTErrorInfo *_Nullable error) {
dispatch_async(self->_userQueue, ^{
userCallback(error);
});
};
}
dispatch_async(_queue, ^{
[self reenterAfterChecksWithPresenceMessage:message callback:cb];
});
}

- (void)update:(id)data {
[self update:data callback:nil];
}
Expand Down Expand Up @@ -344,6 +358,30 @@ - (void)enterOrUpdateAfterChecks:(ARTPresenceAction)action clientId:(NSString *_
[self publishPresence:msg callback:cb];
}

- (void)reenterAfterChecksWithPresenceMessage:(ARTPresenceMessage *)message callback:(ARTCallback)cb {
switch (_channel.state_nosync) {
case ARTRealtimeChannelDetached:
case ARTRealtimeChannelFailed: {
if (cb) {
ARTErrorInfo *channelError = [ARTErrorInfo createWithCode:ARTErrorChannelOperationFailedInvalidState message:[NSString stringWithFormat:@"unable to enter presence channel (incompatible channel state: %@)", ARTRealtimeChannelStateToStr(_channel.state_nosync)]];
cb(channelError);
}
return;
}
default:
break;
}

ARTPresenceMessage *msg = [[ARTPresenceMessage alloc] init];
msg.action = ARTPresenceEnter;
msg.id = message.id; // RTP17g
msg.clientId = message.clientId;
msg.data = message.data;
msg.connectionId = _channel.realtime.connection.id_nosync;

[self publishPresence:msg callback:cb];
}

- (void)leave:(id)data {
[self leave:data callback:nil];
}
Expand Down
2 changes: 2 additions & 0 deletions Source/PrivateHeaders/Ably/ARTPresenceMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)internalAdd:(ARTPresenceMessage *)message;
- (void)internalAdd:(ARTPresenceMessage *)message withSessionId:(NSUInteger)sessionId;

- (void)reenterLocalMembers;

@end

NS_ASSUME_NONNULL_END
2 changes: 2 additions & 0 deletions Source/PrivateHeaders/Ably/ARTRealtimePresence+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sendPendingPresence;
- (void)failPendingPresence:(ARTStatus *)status;

- (void)reenterWithPresenceMessage:(ARTPresenceMessage *)message callback:(ARTCallback)cb;

@property (nonatomic) dispatch_queue_t queue;
@property (readwrite, nonatomic) ARTPresenceAction lastPresenceAction;
@property (readonly, nonatomic) NSMutableArray<ARTQueuedMessage *> *pendingPresence;
Expand Down

0 comments on commit ebc91c2

Please sign in to comment.