From 13fc78e039f45879e3c92e4ba55370ef786e7bbf Mon Sep 17 00:00:00 2001 From: jguz-pubnub Date: Thu, 12 Sep 2024 12:49:09 +0200 Subject: [PATCH 01/10] Added synchronized access to listeners and subscriptions --- Sources/PubNub/Helpers/WeakBox.swift | 30 +++++++----- .../Subscription/SubscriptionSession.swift | 47 +++++++++++++------ 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/Sources/PubNub/Helpers/WeakBox.swift b/Sources/PubNub/Helpers/WeakBox.swift index ffba2013..6ca168a9 100644 --- a/Sources/PubNub/Helpers/WeakBox.swift +++ b/Sources/PubNub/Helpers/WeakBox.swift @@ -29,43 +29,51 @@ final class WeakBox: Hashable where Element: AnyObject, Element: Hashab } struct WeakSet where Element: AnyObject, Element: Hashable { - private var elements: Set> = [] + private var elements: Atomic>> = Atomic([]) init(_ elements: [Element]) { - elements.forEach { self.elements.update(with: WeakBox($0)) } + self.elements.lockedWrite { [elements] currentValue in + elements.forEach { element in + currentValue.update(with: WeakBox(element)) + } + } } // NSSet Operations var allObjects: [Element] { - return elements.compactMap { $0.underlying } + return elements.lockedRead { $0 }.compactMap { $0.underlying } } var count: Int { - return self.elements.count + elements.lockedRead { $0 }.count } mutating func update(_ element: Element) { - elements.update(with: WeakBox(element)) + elements.lockedWrite { [element] in + $0.update(with: WeakBox(element)) + } } mutating func remove(_ element: Element) { - elements.remove(WeakBox(element)) + elements.lockedWrite { [element] in + $0.remove(WeakBox(element)) + } } mutating func removeAll() { - elements.removeAll() + elements.lockedWrite { $0 = Set>() } } } extension WeakSet: Collection { - var startIndex: Set>.Index { return elements.startIndex } - var endIndex: Set>.Index { return elements.endIndex } + var startIndex: Set>.Index { return elements.lockedRead { $0 }.startIndex } + var endIndex: Set>.Index { return elements.lockedRead { $0 }.endIndex } subscript(position: Set>.Index) -> Element? { - return elements[position].underlying + elements.lockedRead { $0[position] }.underlying } func index(after index: Set>.Index) -> Set>.Index { - return elements.index(after: index) + elements.lockedRead { $0 }.index(after: index) } } diff --git a/Sources/PubNub/Subscription/SubscriptionSession.swift b/Sources/PubNub/Subscription/SubscriptionSession.swift index 0b3fe32a..dba7d714 100644 --- a/Sources/PubNub/Subscription/SubscriptionSession.swift +++ b/Sources/PubNub/Subscription/SubscriptionSession.swift @@ -64,8 +64,8 @@ class SubscriptionSession: EventEmitter, StatusEmitter { return statusListener }() - private var globalChannelSubscriptions: [String: Subscription] = [:] - private var globalGroupSubscriptions: [String: Subscription] = [:] + private var globalChannelSubscriptions: Atomic<[String: Subscription]> = Atomic([:]) + private var globalGroupSubscriptions: Atomic<[String: Subscription]> = Atomic([:]) private let strategy: any SubscriptionSessionStrategy init( @@ -125,16 +125,29 @@ class SubscriptionSession: EventEmitter, StatusEmitter { and: channelGroupSubscriptions, at: cursor?.timetoken ) - for subscription in channelSubscriptions { - subscription.subscriptionNames.compactMap { $0 }.forEach { - globalChannelSubscriptions[$0] = subscription + + let channelSubsToMerge = channelSubscriptions.reduce( + into: [String: Subscription]() + ) { accumulatedValue, subscription in + subscription.subscriptionNames.forEach { + accumulatedValue[$0] = subscription } } - for subscription in channelGroupSubscriptions { - subscription.subscriptionNames.compactMap { $0 }.forEach { - globalGroupSubscriptions[$0] = subscription + + let channelGroupSubsToMerge = channelGroupSubscriptions.reduce( + into: [String: Subscription]() + ) { accumulatedValue, subscription in + subscription.subscriptionNames.forEach { + accumulatedValue[$0] = subscription } } + + globalChannelSubscriptions.lockedWrite { + $0.merge(channelSubsToMerge) { (_, new) in new } + } + globalGroupSubscriptions.lockedWrite { + $0.merge(channelGroupSubsToMerge) { (_, new) in new } + } } // MARK: - Reconnect @@ -163,15 +176,21 @@ class SubscriptionSession: EventEmitter, StatusEmitter { presenceOnly ? [$0.presenceChannelName] : [$0, $0.presenceChannelName] } internalUnsubscribe( - from: globalChannelSubscriptions.compactMap { channelNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, - and: globalGroupSubscriptions.compactMap { groupNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, + from: globalChannelSubscriptions.lockedRead { $0 }.compactMap { channelNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, + and: globalGroupSubscriptions.lockedRead { $0 }.compactMap { groupNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, presenceOnly: presenceOnly ) - channelNamesToUnsubscribe.forEach { - globalChannelSubscriptions.removeValue(forKey: $0) + + globalChannelSubscriptions.lockedWrite { currentContainer in + channelNamesToUnsubscribe.forEach { + currentContainer.removeValue(forKey: $0) + } } - groupNamesToUnsubscribe.forEach { - globalGroupSubscriptions.removeValue(forKey: $0) + + globalGroupSubscriptions.lockedWrite { currentContainer in + groupNamesToUnsubscribe.forEach { + currentContainer.removeValue(forKey: $0) + } } } From be6abfc6c08846d4b469b6ef04577c6272de82ae Mon Sep 17 00:00:00 2001 From: jguz-pubnub Date: Thu, 12 Sep 2024 13:35:34 +0200 Subject: [PATCH 02/10] SwiftLint --- .../PubNub/Subscription/SubscriptionSession.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/PubNub/Subscription/SubscriptionSession.swift b/Sources/PubNub/Subscription/SubscriptionSession.swift index dba7d714..35b9fff0 100644 --- a/Sources/PubNub/Subscription/SubscriptionSession.swift +++ b/Sources/PubNub/Subscription/SubscriptionSession.swift @@ -125,7 +125,7 @@ class SubscriptionSession: EventEmitter, StatusEmitter { and: channelGroupSubscriptions, at: cursor?.timetoken ) - + let channelSubsToMerge = channelSubscriptions.reduce( into: [String: Subscription]() ) { accumulatedValue, subscription in @@ -133,7 +133,7 @@ class SubscriptionSession: EventEmitter, StatusEmitter { accumulatedValue[$0] = subscription } } - + let channelGroupSubsToMerge = channelGroupSubscriptions.reduce( into: [String: Subscription]() ) { accumulatedValue, subscription in @@ -141,12 +141,12 @@ class SubscriptionSession: EventEmitter, StatusEmitter { accumulatedValue[$0] = subscription } } - + globalChannelSubscriptions.lockedWrite { - $0.merge(channelSubsToMerge) { (_, new) in new } + $0.merge(channelSubsToMerge) { _, new in new } } globalGroupSubscriptions.lockedWrite { - $0.merge(channelGroupSubsToMerge) { (_, new) in new } + $0.merge(channelGroupSubsToMerge) { _, new in new } } } @@ -180,13 +180,13 @@ class SubscriptionSession: EventEmitter, StatusEmitter { and: globalGroupSubscriptions.lockedRead { $0 }.compactMap { groupNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, presenceOnly: presenceOnly ) - + globalChannelSubscriptions.lockedWrite { currentContainer in channelNamesToUnsubscribe.forEach { currentContainer.removeValue(forKey: $0) } } - + globalGroupSubscriptions.lockedWrite { currentContainer in groupNamesToUnsubscribe.forEach { currentContainer.removeValue(forKey: $0) From b7ada07522fd87905d78abd8284fbf5224d57e13 Mon Sep 17 00:00:00 2001 From: jguz-pubnub Date: Thu, 12 Sep 2024 14:28:24 +0200 Subject: [PATCH 03/10] SwiftLint (Codacy) --- Sources/PubNub/Subscription/SubscriptionSession.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/PubNub/Subscription/SubscriptionSession.swift b/Sources/PubNub/Subscription/SubscriptionSession.swift index 35b9fff0..3ecb7bd7 100644 --- a/Sources/PubNub/Subscription/SubscriptionSession.swift +++ b/Sources/PubNub/Subscription/SubscriptionSession.swift @@ -176,8 +176,12 @@ class SubscriptionSession: EventEmitter, StatusEmitter { presenceOnly ? [$0.presenceChannelName] : [$0, $0.presenceChannelName] } internalUnsubscribe( - from: globalChannelSubscriptions.lockedRead { $0 }.compactMap { channelNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, - and: globalGroupSubscriptions.lockedRead { $0 }.compactMap { groupNamesToUnsubscribe.contains($0.key) ? $0.value : nil }, + from: globalChannelSubscriptions.lockedRead { $0 }.compactMap { + channelNamesToUnsubscribe.contains($0.key) ? $0.value : nil + }, + and: globalGroupSubscriptions.lockedRead { $0 }.compactMap { + groupNamesToUnsubscribe.contains($0.key) ? $0.value : nil + }, presenceOnly: presenceOnly ) From cfc9a53c41cd4e2dfa75eaecef693971c0dfddbe Mon Sep 17 00:00:00 2001 From: jguz-pubnub <102806147+jguz-pubnub@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:49:40 +0200 Subject: [PATCH 04/10] Update Sources/PubNub/Helpers/WeakBox.swift Co-authored-by: Serhii Mamontov --- Sources/PubNub/Helpers/WeakBox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PubNub/Helpers/WeakBox.swift b/Sources/PubNub/Helpers/WeakBox.swift index 6ca168a9..1d928ed6 100644 --- a/Sources/PubNub/Helpers/WeakBox.swift +++ b/Sources/PubNub/Helpers/WeakBox.swift @@ -41,7 +41,7 @@ struct WeakSet where Element: AnyObject, Element: Hashable { // NSSet Operations var allObjects: [Element] { - return elements.lockedRead { $0 }.compactMap { $0.underlying } + return elements.lockedRead { $0.compactMap { $0.underlying } } } var count: Int { From 4dadc6c6d22c06ec8813bb781e37ae23d4a98bda Mon Sep 17 00:00:00 2001 From: jguz-pubnub <102806147+jguz-pubnub@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:49:52 +0200 Subject: [PATCH 05/10] Update Sources/PubNub/Helpers/WeakBox.swift Co-authored-by: Serhii Mamontov --- Sources/PubNub/Helpers/WeakBox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PubNub/Helpers/WeakBox.swift b/Sources/PubNub/Helpers/WeakBox.swift index 1d928ed6..fa20cf17 100644 --- a/Sources/PubNub/Helpers/WeakBox.swift +++ b/Sources/PubNub/Helpers/WeakBox.swift @@ -45,7 +45,7 @@ struct WeakSet where Element: AnyObject, Element: Hashable { } var count: Int { - elements.lockedRead { $0 }.count + elements.lockedRead { $0.count } } mutating func update(_ element: Element) { From 23f4fd6c686c145f9115b16cbcc7f613152817f9 Mon Sep 17 00:00:00 2001 From: jguz-pubnub <102806147+jguz-pubnub@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:50:06 +0200 Subject: [PATCH 06/10] Update Sources/PubNub/Helpers/WeakBox.swift Co-authored-by: Serhii Mamontov --- Sources/PubNub/Helpers/WeakBox.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/PubNub/Helpers/WeakBox.swift b/Sources/PubNub/Helpers/WeakBox.swift index fa20cf17..93781f13 100644 --- a/Sources/PubNub/Helpers/WeakBox.swift +++ b/Sources/PubNub/Helpers/WeakBox.swift @@ -66,8 +66,8 @@ struct WeakSet where Element: AnyObject, Element: Hashable { } extension WeakSet: Collection { - var startIndex: Set>.Index { return elements.lockedRead { $0 }.startIndex } - var endIndex: Set>.Index { return elements.lockedRead { $0 }.endIndex } + var startIndex: Set>.Index { return elements.lockedRead { $0.startIndex } } + var endIndex: Set>.Index { return elements.lockedRead { $0.endIndex } } subscript(position: Set>.Index) -> Element? { elements.lockedRead { $0[position] }.underlying From ffd868e885070c5b8b81610c647be7c400a1ecf0 Mon Sep 17 00:00:00 2001 From: jguz-pubnub <102806147+jguz-pubnub@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:50:20 +0200 Subject: [PATCH 07/10] Update Sources/PubNub/Helpers/WeakBox.swift Co-authored-by: Serhii Mamontov --- Sources/PubNub/Helpers/WeakBox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PubNub/Helpers/WeakBox.swift b/Sources/PubNub/Helpers/WeakBox.swift index 93781f13..45b43b64 100644 --- a/Sources/PubNub/Helpers/WeakBox.swift +++ b/Sources/PubNub/Helpers/WeakBox.swift @@ -70,7 +70,7 @@ extension WeakSet: Collection { var endIndex: Set>.Index { return elements.lockedRead { $0.endIndex } } subscript(position: Set>.Index) -> Element? { - elements.lockedRead { $0[position] }.underlying + elements.lockedRead { $0[position].underlying } } func index(after index: Set>.Index) -> Set>.Index { From db81292711d9782e561592182321a5e30a7a897e Mon Sep 17 00:00:00 2001 From: jguz-pubnub <102806147+jguz-pubnub@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:50:37 +0200 Subject: [PATCH 08/10] Update Sources/PubNub/Helpers/WeakBox.swift Co-authored-by: Serhii Mamontov --- Sources/PubNub/Helpers/WeakBox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PubNub/Helpers/WeakBox.swift b/Sources/PubNub/Helpers/WeakBox.swift index 45b43b64..21f3f120 100644 --- a/Sources/PubNub/Helpers/WeakBox.swift +++ b/Sources/PubNub/Helpers/WeakBox.swift @@ -74,6 +74,6 @@ extension WeakSet: Collection { } func index(after index: Set>.Index) -> Set>.Index { - elements.lockedRead { $0 }.index(after: index) + elements.lockedRead { $0.index(after: index) } } } From 29b97f86b0870946de35c04505c15d542432484e Mon Sep 17 00:00:00 2001 From: jguz-pubnub <102806147+jguz-pubnub@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:51:21 +0200 Subject: [PATCH 09/10] Update Sources/PubNub/Subscription/SubscriptionSession.swift Co-authored-by: Serhii Mamontov --- Sources/PubNub/Subscription/SubscriptionSession.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/PubNub/Subscription/SubscriptionSession.swift b/Sources/PubNub/Subscription/SubscriptionSession.swift index 3ecb7bd7..4f1789c3 100644 --- a/Sources/PubNub/Subscription/SubscriptionSession.swift +++ b/Sources/PubNub/Subscription/SubscriptionSession.swift @@ -176,12 +176,12 @@ class SubscriptionSession: EventEmitter, StatusEmitter { presenceOnly ? [$0.presenceChannelName] : [$0, $0.presenceChannelName] } internalUnsubscribe( - from: globalChannelSubscriptions.lockedRead { $0 }.compactMap { + from: globalChannelSubscriptions.lockedRead { $0.compactMap { channelNamesToUnsubscribe.contains($0.key) ? $0.value : nil - }, - and: globalGroupSubscriptions.lockedRead { $0 }.compactMap { + } }, + and: globalGroupSubscriptions.lockedRead { $0.compactMap { groupNamesToUnsubscribe.contains($0.key) ? $0.value : nil - }, + } }, presenceOnly: presenceOnly ) From ae73e63e35abb53e76d05e107e4050a31775f3c8 Mon Sep 17 00:00:00 2001 From: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:41:37 +0000 Subject: [PATCH 10/10] PubNub SDK 7.3.3 release. --- .pubnub.yml | 9 +++++++-- PubNub.xcodeproj/project.pbxproj | 16 ++++++++-------- PubNubSwift.podspec | 2 +- Sources/PubNub/Helpers/Constants.swift | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.pubnub.yml b/.pubnub.yml index 25401336..20546edb 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,9 +1,14 @@ --- name: swift scm: github.com/pubnub/swift -version: "7.3.2" +version: "7.3.3" schema: 1 changelog: + - date: 2024-09-13 + version: 7.3.3 + changes: + - type: bug + text: "Added synchronized access inside `WeakSet` and for global subscriptions." - date: 2024-07-22 version: 7.3.2 changes: @@ -564,7 +569,7 @@ sdks: - distribution-type: source distribution-repository: GitHub release package-name: PubNub - location: https://github.com/pubnub/swift/archive/refs/tags/7.3.2.zip + location: https://github.com/pubnub/swift/archive/refs/tags/7.3.3.zip supported-platforms: supported-operating-systems: macOS: diff --git a/PubNub.xcodeproj/project.pbxproj b/PubNub.xcodeproj/project.pbxproj index 6f8f3f80..01ee7ccc 100644 --- a/PubNub.xcodeproj/project.pbxproj +++ b/PubNub.xcodeproj/project.pbxproj @@ -3847,7 +3847,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -3898,7 +3898,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -4006,7 +4006,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -4059,7 +4059,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -4180,7 +4180,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -4232,7 +4232,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -4712,7 +4712,7 @@ "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; @@ -4754,7 +4754,7 @@ "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 7.3.2; + MARKETING_VERSION = 7.3.3; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; diff --git a/PubNubSwift.podspec b/PubNubSwift.podspec index ad5da0dc..9b7321d6 100644 --- a/PubNubSwift.podspec +++ b/PubNubSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'PubNubSwift' - s.version = '7.3.2' + s.version = '7.3.3' s.homepage = 'https://github.com/pubnub/swift' s.documentation_url = 'https://www.pubnub.com/docs/swift-native/pubnub-swift-sdk' s.authors = { 'PubNub, Inc.' => 'support@pubnub.com' } diff --git a/Sources/PubNub/Helpers/Constants.swift b/Sources/PubNub/Helpers/Constants.swift index a34ef409..93efe562 100644 --- a/Sources/PubNub/Helpers/Constants.swift +++ b/Sources/PubNub/Helpers/Constants.swift @@ -57,7 +57,7 @@ public enum Constant { static let pubnubSwiftSDKName: String = "PubNubSwift" - static let pubnubSwiftSDKVersion: String = "7.3.2" + static let pubnubSwiftSDKVersion: String = "7.3.3" static let appBundleId: String = { if let info = Bundle.main.infoDictionary,