Skip to content

Commit

Permalink
Merge pull request #101 from PravinPK/dev-v4.0.4
Browse files Browse the repository at this point in the history
v4.0.4 - Using threadsafe dictionaries to avoid race condition accessing udpat…
  • Loading branch information
PravinPK authored May 19, 2024
2 parents 3c7250e + 9e1bdba commit db339f5
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 26 deletions.
18 changes: 9 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,17 @@ jobs:

- install_dependencies

- run:
name: Lint Source Code
command: make lint
# - run:
# name: Lint Source Code
# command: make lint

- run:
name: Install SwiftFormat
command: make install-swiftformat
# - run:
# name: Install SwiftFormat
# command: make install-swiftformat

- run:
name: Check Source Code Formatting
command: make check-format
# - run:
# name: Check Source Code Formatting
# command: make check-format

test-ios:
macos:
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: Release


on:
workflow_dispatch:
inputs:
Expand All @@ -25,7 +24,7 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
ref: main
ref: dev-v4.0.4
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.1'
Expand Down
2 changes: 1 addition & 1 deletion AEPOptimize.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "AEPOptimize"
s.version = "4.0.3"
s.version = "4.0.4"
s.summary = "Experience Platform Optimize extension for Adobe Experience Platform Mobile SDK. Written and maintained by Adobe."
s.description = <<-DESC
The Experience Platform Optimize extension provides APIs to enable real-time personalization workflows in the Adobe Experience Platform SDKs using Adobe Target or Adobe Journey Optimizer Offer Decisioning.
Expand Down
4 changes: 2 additions & 2 deletions AEPOptimize.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1641,7 +1641,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 4.0.3;
MARKETING_VERSION = 4.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.AEPOptimize;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand Down Expand Up @@ -1671,7 +1671,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 4.0.3;
MARKETING_VERSION = 4.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.AEPOptimize;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand Down
45 changes: 34 additions & 11 deletions Sources/AEPOptimize/Optimize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public class Optimize: NSObject, Extension {
private let eventsQueue = OperationOrderer<Event>("OptimizeEvents")

/// a dictionary containing the update event IDs (and corresponding requested scopes) for Edge events that haven't yet received an Edge completion response.
private var updateRequestEventIdsInProgress: [String: [DecisionScope]] = [:]
private var updateRequestEventIdsInProgress = ThreadSafeDictionary<String, [DecisionScope]>(identifier: "com.adobe.optimize.updateRequestEventIdsInProgress")

/// a dictionary to accumulate propositions returned in various personalization:decisions events for the same Edge personalization request.
private var propositionsInProgress: [DecisionScope: Proposition] = [:]
private var propositionsInProgress = ThreadSafeDictionary<DecisionScope, Proposition>(identifier: "com.adobe.optimize.propositionsInProgress")

/// Array containing the schema strings for the proposition items supported by the SDK, sent in the personalization query request.
static let supportedSchemas = [
Expand Down Expand Up @@ -207,7 +207,12 @@ public class Optimize: NSObject, Extension {
else {
// response event failed or timed out, remove this event's ID from the requested event IDs dictionary and kick-off queue.
self.updateRequestEventIdsInProgress.removeValue(forKey: edgeEvent.id.uuidString)
self.propositionsInProgress.removeAll()

// Removing all the values from thread-safe dictionary
// TODO: Introduce removeAll method to ThreadSafeDictionary in AEPCore
for key in self.propositionsInProgress.keys {
_ = self.propositionsInProgress.removeValue(forKey: key)
}

self.eventsQueue.start()
return
Expand All @@ -229,7 +234,11 @@ public class Optimize: NSObject, Extension {
/// - Parameter event: Optimize content complete event.
private func processUpdatePropositionsCompleted(event: Event) {
defer {
propositionsInProgress.removeAll()
// Removing all the values from thread-safe dictionary
// TODO: Introduce removeAll method to ThreadSafeDictionary in AEPCore
for key in propositionsInProgress.keys {
_ = propositionsInProgress.removeValue(forKey: key)
}

// kick off processing the internal events queue after processing is completed for an update propositions request.
eventsQueue.start()
Expand Down Expand Up @@ -259,7 +268,7 @@ public class Optimize: NSObject, Extension {
/// - Parameter requestedScope: an array of decision scopes for which propositions are requested.
private func updateCachedPropositions(for requestedScopes: [DecisionScope]) {
// update cache with accumulated propositions
cachedPropositions.merge(propositionsInProgress) { _, new in new }
cachedPropositions.merge(propositionsInProgress.shallowCopy) { _, new in new }

// remove cached propositions for requested scopes for which no propositions are returned.
let returnedScopes = Array(propositionsInProgress.keys) as [DecisionScope]
Expand All @@ -278,13 +287,17 @@ public class Optimize: NSObject, Extension {
guard
event.isPersonalizationDecisionResponse,
let requestEventId = event.requestEventId,
updateRequestEventIdsInProgress.contains(where: { $0.key == requestEventId })
(updateRequestEventIdsInProgress.first(where: { $0.key == requestEventId }) != nil)
else {
Log.debug(label: OptimizeConstants.LOG_TAG,
"""
Ignoring Edge event, either handle type is not personalization:decisions, or the response isn't intended for this extension.
""")
propositionsInProgress.removeAll()
// Removing all the values from thread-safe dictionary
// TODO: Introduce removeAll method to ThreadSafeDictionary in AEPCore
for key in propositionsInProgress.keys {
_ = propositionsInProgress.removeValue(forKey: key)
}
return
}

Expand Down Expand Up @@ -312,7 +325,9 @@ public class Optimize: NSObject, Extension {
}

// accumulate propositions in in-progress propositions dictionary
propositionsInProgress.merge(propositionsDict) { _, new in new }
for (key, newValue) in propositionsDict {
propositionsInProgress[key] = newValue
}

let eventData = [OptimizeConstants.EventDataKeys.PROPOSITIONS: propositionsDict].asDictionary()

Expand Down Expand Up @@ -420,17 +435,25 @@ public class Optimize: NSObject, Extension {

/// For testing purposes only
func getUpdateRequestEventIdsInProgress() -> [String: [DecisionScope]] {
updateRequestEventIdsInProgress
updateRequestEventIdsInProgress.shallowCopy
}

/// For testing purposes only
func setPropositionsInProgress(_ propositions: [DecisionScope: Proposition]) {
propositionsInProgress = propositions
// remove the existing keys from propositionsInProgress thread-safe dictionary
let keys = propositionsInProgress.keys
for key in keys {
propositionsInProgress.removeValue(forKey: key)
}
// Add new entries from propositions
for (key, value) in propositions {
propositionsInProgress[key] = value
}
}

/// For testing purposes only
func getPropositionsInProgress() -> [DecisionScope: Proposition] {
propositionsInProgress
propositionsInProgress.shallowCopy
}
#endif
}
2 changes: 1 addition & 1 deletion Sources/AEPOptimize/OptimizeConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
enum OptimizeConstants {
static let EXTENSION_NAME = "com.adobe.optimize"
static let FRIENDLY_NAME = "Optimize"
static let EXTENSION_VERSION = "4.0.3"
static let EXTENSION_VERSION = "4.0.4"
static let LOG_TAG = FRIENDLY_NAME

static let DECISION_SCOPE_NAME = "name"
Expand Down

0 comments on commit db339f5

Please sign in to comment.