Skip to content

Commit

Permalink
Ensure thread-safe access to messages list
Browse files Browse the repository at this point in the history
- Added synchronization to `makeRedisplayMessagesAvailableWithTriggers` and `attemptToShowInAppMessage` to prevent concurrent modification issues
- Refactored `evaluateInAppMessages` to collect messages for display inside a synchronized block and process them outside to avoid suspension points within critical sections
  • Loading branch information
jennantilla committed Jul 30, 2024
1 parent f9620c1 commit d4b4fce
Showing 1 changed file with 18 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ internal class InAppMessagesManager(
private val fetchIAMMutex = Mutex()
private var lastTimeFetchedIAMs: Long? = null

private val lock = Any()

override var paused: Boolean
get() = _state.paused
set(value) {
Expand Down Expand Up @@ -265,16 +267,22 @@ internal class InAppMessagesManager(
*/
private suspend fun evaluateInAppMessages() {
Logging.debug("InAppMessagesManager.evaluateInAppMessages()")

for (message in messages) {
// Make trigger evaluation first, dynamic trigger might change "trigger changed" flag value for redisplay messages
if (_triggerController.evaluateMessageTriggers(message)) {
setDataForRedisplay(message)
if (!dismissedMessages.contains(message.messageId) && !message.isFinished) {
queueMessageForDisplay(message)
val messagesToQueue = mutableListOf<InAppMessage>()

synchronized(lock) {
for (message in messages) {
if (_triggerController.evaluateMessageTriggers(message)) {
setDataForRedisplay(message)
if (!dismissedMessages.contains(message.messageId) && !message.isFinished) {
messagesToQueue.add(message)
}
}
}
}

for (message in messagesToQueue) {
queueMessageForDisplay(message)
}
}

/**
Expand Down Expand Up @@ -458,14 +466,15 @@ internal class InAppMessagesManager(
newTriggersKeys: Collection<String>,
isNewTriggerAdded: Boolean,
) {
for (message in messages) {
synchronized {
for (message in messages) {
val isMessageDisplayed = redisplayedInAppMessages.contains(message)
val isTriggerOnMessage = _triggerController.isTriggerOnMessage(message, newTriggersKeys)
val isOnlyDynamicTriggers = _triggerController.messageHasOnlyDynamicTriggers(message)
if (!message.isTriggerChanged && isMessageDisplayed && (isTriggerOnMessage || isNewTriggerAdded && isOnlyDynamicTriggers)) {
Logging.debug("InAppMessagesManager.makeRedisplayMessagesAvailableWithTriggers: Trigger changed for message: $message")
message.isTriggerChanged = true
}
}
}
}

Expand Down

0 comments on commit d4b4fce

Please sign in to comment.