diff --git a/Sources/Confidence/Confidence.swift b/Sources/Confidence/Confidence.swift index 507ae8f0..659cf3c3 100644 --- a/Sources/Confidence/Confidence.swift +++ b/Sources/Confidence/Confidence.swift @@ -49,7 +49,7 @@ public class Confidence: ConfidenceEventSender { self.remoteFlagResolver = remoteFlagResolver self.debugLogger = debugLogger if let visitorId { - putContext(context: ["visitor_id": ConfidenceValue.init(string: visitorId)]) + putContextLocal(context: ["visitor_id": ConfidenceValue.init(string: visitorId)]) } } @@ -195,10 +195,10 @@ public class Confidence: ConfidenceEventSender { if let contextProducer = producer as? ConfidenceContextProducer { contextProducer.produceContexts() .sink { [weak self] context in - guard let self = self else { - return + Task { [weak self] in + guard let self = self else { return } + await self.putContext(context: context) } - self.putContext(context: context) } .store(in: &cancellables) } @@ -233,6 +233,23 @@ public class Confidence: ConfidenceEventSender { } } + + public func putContextLocal(context: ConfidenceStruct, removeKeys removedKeys: [String] = []) { + withLock { confidence in + var map = confidence.contextSubject.value + for removedKey in removedKeys { + map.removeValue(forKey: removedKey) + } + for entry in context { + map.updateValue(entry.value, forKey: entry.key) + } + confidence.contextSubject.value = map + confidence.debugLogger?.logContext( + action: "PutContext", + context: confidence.contextSubject.value) + } + } + public func putContext(context: ConfidenceStruct) async { await withLockAsync { confidence in var map = confidence.contextSubject.value @@ -242,15 +259,19 @@ public class Confidence: ConfidenceEventSender { confidence.contextSubject.value = map do { try await self.fetchAndActivate() - confidence.debugLogger?.logContext(action: "PutContext", context: confidence.contextSubject.value) + confidence.debugLogger?.logContext( + action: "PutContext & FetchAndActivate", + context: confidence.contextSubject.value) } catch { - confidence.debugLogger?.logMessage(message: "Error when putting context: \(error)", isWarning: true) + confidence.debugLogger?.logMessage( + message: "Error when putting context: \(error)", + isWarning: true) } } } - public func putContext(context: ConfidenceStruct, removeKeys removedKeys: [String] = []) { - withLock { confidence in + public func putContext(context: ConfidenceStruct, removeKeys removedKeys: [String] = []) async { + await withLockAsync { confidence in var map = confidence.contextSubject.value for removedKey in removedKeys { map.removeValue(forKey: removedKey) @@ -259,17 +280,35 @@ public class Confidence: ConfidenceEventSender { map.updateValue(entry.value, forKey: entry.key) } confidence.contextSubject.value = map - confidence.debugLogger?.logContext(action: "PutContext", context: confidence.contextSubject.value) + do { + try await self.fetchAndActivate() + confidence.debugLogger?.logContext( + action: "PutContext & FetchAndActivate", + context: confidence.contextSubject.value) + } catch { + confidence.debugLogger?.logMessage( + message: "Error when putting context: \(error)", + isWarning: true) + } } } - public func removeKey(key: String) { - withLock { confidence in + public func removeKey(key: String) async { + await withLockAsync { confidence in var map = confidence.contextSubject.value map.removeValue(forKey: key) confidence.contextSubject.value = map confidence.removedContextKeys.insert(key) - confidence.debugLogger?.logContext(action: "RemoveContext", context: confidence.contextSubject.value) + do { + try await self.fetchAndActivate() + confidence.debugLogger?.logContext( + action: "RemoveContextKey & FetchAndActivate", + context: confidence.contextSubject.value) + } catch { + confidence.debugLogger?.logMessage( + message: "Error when removing context key: \(error)", + isWarning: true) + } } } diff --git a/Sources/Confidence/ConfidenceEventSender.swift b/Sources/Confidence/ConfidenceEventSender.swift index ed1d962f..ce52762b 100644 --- a/Sources/Confidence/ConfidenceEventSender.swift +++ b/Sources/Confidence/ConfidenceEventSender.swift @@ -26,7 +26,7 @@ public protocol ConfidenceEventSender: ConfidenceContextProvider { Removes entry from localcontext data It hides entries with this key from parents' data (without modifying parents' data) */ - func removeKey(key: String) + func removeKey(key: String) async /** Creates a child event sender instance that maintains access to its parent's data */ diff --git a/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift b/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift index 538518a3..e055e7ef 100644 --- a/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift +++ b/Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift @@ -86,7 +86,7 @@ public class ConfidenceFeatureProvider: FeatureProvider { } private func updateConfidenceContext(context: EvaluationContext, removedKeys: [String] = []) { - confidence.putContext(context: ConfidenceTypeMapper.from(ctx: context), removeKeys: removedKeys) + confidence.putContextLocal(context: ConfidenceTypeMapper.from(ctx: context), removeKeys: removedKeys) } public func getBooleanEvaluation(key: String, defaultValue: Bool, context: EvaluationContext?) throws