Skip to content

Conversation

@jguz-pubnub
Copy link
Contributor

@jguz-pubnub jguz-pubnub commented Dec 5, 2025

fix(chat): modify the entities to hold a strong Chat reference

@pubnub-ops-terraform
Copy link
Contributor

pubnub-ops-terraform commented Dec 5, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@@ -27,15 +27,13 @@ class ChatAdapter {
}

static func associate(chat: ChatImpl, with kotlinChat: PubNubChat.ChatImpl) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class maintains bidirectional associations between Swift's ChatImpl and KMP's PubNubChat.ChatImpl instances. It's required because KMP entities (Channel, User, Message) must be initialized with KMP Chat references, and these entities store strong references back to Chat within the KMP layer

if !associations.contains(where: { !$0.isEmpty() && $0.chat !== chat && $0.kotlinChat !== kotlinChat }) {
associations.append(.init(chat: chat, kotlinChat: kotlinChat))
}
queue.sync {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that the new code always appends, so you definitely can have multiple Association objects for the same kotlinChat or chat.

Given your requirement:

maintains bidirectional associations between Swift's ChatImpl and KMP's ChatImpl

you almost certainly want:

At most one association per ChatImpl
At most one association per PubNubChat.ChatImpl
Otherwise map(chat:) just returns the first match and leaves dangling duplicates around.

Here’s a version aligned with the “strict 1–1 mapping” idea, using your new serial queue with sync:

static func associate(chat: ChatImpl, with kotlinChat: PubNubChat.ChatImpl) {
  queue.sync {
    // Drop dead associations first
    associations.removeAll { $0.isEmpty() }

    // If there is an existing association for either side, reuse/update it
    if let existing = associations.first(where: {
      !$0.isEmpty() && ($0.chat === chat || $0.kotlinChat === kotlinChat)
    }) {
      // You’ll need these setters or make _chat/_kotlinChat internal
      existing._chat = chat
      existing._kotlinChat = kotlinChat
    } else {
      associations.append(.init(chat: chat, kotlinChat: kotlinChat))
    }
  }
}

Then you’d need to relax Association a bit:

class Association {
  // swiftlint:disable:next force_unwrapping
  var chat: ChatImpl { _chat! }
  // swiftlint:disable:next force_unwrapping
  var kotlinChat: PubNubChat.ChatImpl { _kotlinChat! }

  // make these internal(set) so associate() can adjust them
  weak var _chat: ChatImpl?
  weak var _kotlinChat: PubNubChat.ChatImpl?

  init(chat: ChatImpl, kotlinChat: PubNubChat.ChatImpl) {
    _chat = chat
    _kotlinChat = kotlinChat
  }

  func isEmpty() -> Bool {
    _chat == nil || _kotlinChat == nil
  }
}

This gives you:
1–1 mapping between Swift and KMP chat instances.
Reuse/repair of associations when one side is recreated but the other is still alive.
No growth of duplicates over time.

Copy link
Contributor Author

@jguz-pubnub jguz-pubnub Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely got rid of these associations and ensured entities hold a strong reference to their Chat instance

@jguz-pubnub jguz-pubnub changed the title Fix race conditions in ChatAdapter and remove concurrent queue Change entities to hold strong ChatImpl references Dec 8, 2025
@jguz-pubnub jguz-pubnub changed the title Change entities to hold strong ChatImpl references Change entities to hold strong Chat references Dec 8, 2025
@jguz-pubnub jguz-pubnub changed the title Change entities to hold strong Chat references Modify the entities to hold a strong Chat reference Dec 10, 2025
@jguz-pubnub
Copy link
Contributor Author

@pubnub-release-bot release as 0.33.0

@jguz-pubnub jguz-pubnub merged commit 7c07f7e into master Dec 10, 2025
8 of 12 checks passed
@jguz-pubnub jguz-pubnub deleted the fix/chat-adapter branch December 10, 2025 12:51
@pubnub-release-bot
Copy link

🚀 Release successfully completed 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants