diff --git a/Split/Api/DefaultSplitClient.swift b/Split/Api/DefaultSplitClient.swift index fe328c93..3da3cadb 100644 --- a/Split/Api/DefaultSplitClient.swift +++ b/Split/Api/DefaultSplitClient.swift @@ -1,11 +1,5 @@ -// -// DefaultSplitClient.swift -// Split -// // Created by Brian Sztamfater on 20/9/17. // Modified by Natalia Stele on 11/10/17. -// -// import Foundation @@ -55,7 +49,7 @@ public final class DefaultSplitClient: NSObject, SplitClient, TelemetrySplitClie } } -// MARK: Events +// MARK: Customers Listeners extension DefaultSplitClient { public func on(event: SplitEvent, execute action: @escaping SplitAction) { @@ -173,7 +167,7 @@ extension DefaultSplitClient { } } -// MARK: Track Events +// MARK: Tracking extension DefaultSplitClient { public func track(trafficType: String, eventType: String) -> Bool { @@ -223,7 +217,7 @@ extension DefaultSplitClient { } } -// MARK: Persistent attributes feature +// MARK: Persistence extension DefaultSplitClient { public func setAttribute(name: String, value: Any) -> Bool { @@ -265,8 +259,7 @@ extension DefaultSplitClient { } private func isValidAttribute(_ value: Any) -> Bool { - return anyValueValidator.isPrimitiveValue(value: value) || - anyValueValidator.isList(value: value) + return anyValueValidator.isPrimitiveValue(value: value) || anyValueValidator.isList(value: value) } private func logInvalidAttribute(name: String) { @@ -275,31 +268,31 @@ extension DefaultSplitClient { } private func attributesStorage() -> AttributesStorage { - return storageContainer.attributesStorage + storageContainer.attributesStorage } } -// MARK: By Sets evaluation +// MARK: By Flagsets extension DefaultSplitClient { public func getTreatmentsByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: String] { - return treatmentManager.getTreatmentsByFlagSet(flagSet: flagSet, attributes: attributes, evaluationOptions: nil) + treatmentManager.getTreatmentsByFlagSet(flagSet: flagSet, attributes: attributes, evaluationOptions: nil) } public func getTreatmentsByFlagSets(_ flagSets: [String], attributes: [String: Any]?) -> [String: String] { - return treatmentManager.getTreatmentsByFlagSets(flagSets: flagSets, attributes: attributes, evaluationOptions: nil) + treatmentManager.getTreatmentsByFlagSets(flagSets: flagSets, attributes: attributes, evaluationOptions: nil) } public func getTreatmentsWithConfigByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: SplitResult] { - return treatmentManager.getTreatmentsWithConfigByFlagSet(flagSet: flagSet, attributes: attributes, evaluationOptions: nil) + treatmentManager.getTreatmentsWithConfigByFlagSet(flagSet: flagSet, attributes: attributes, evaluationOptions: nil) } public func getTreatmentsWithConfigByFlagSets(_ flagSets: [String], attributes: [String: Any]?) -> [String: SplitResult] { - return treatmentManager.getTreatmentsWithConfigByFlagSets(flagSets: flagSets, attributes: attributes, evaluationOptions: nil) + treatmentManager.getTreatmentsWithConfigByFlagSets(flagSets: flagSets, attributes: attributes, evaluationOptions: nil) } } -// MARK: Flush / Destroy +// MARK: Lifecycle extension DefaultSplitClient { private func syncFlush() { diff --git a/Split/Api/FailHelpers.swift b/Split/Api/FailHelpers.swift index fc6eae22..95234ced 100644 --- a/Split/Api/FailHelpers.swift +++ b/Split/Api/FailHelpers.swift @@ -1,10 +1,5 @@ -// -// FailHelpers.swift -// Split -// // Created by Javier Avrudsky on 24-Apr-2022. // Copyright © 2022 Split. All rights reserved. -// import Foundation @@ -57,42 +52,38 @@ class FailedClient: SplitClient { func on(event: SplitEvent, execute action: @escaping SplitAction) { } - func on(event: SplitEvent, runInBackground: Bool, - execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, runInBackground: Bool, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, - queue: DispatchQueue, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, queue: DispatchQueue, execute action: @escaping SplitAction) {} func on(event: SplitEvent, executeWithMetadata: @escaping SplitActionWithMetadata) {} func track(trafficType: String, eventType: String) -> Bool { - return false + false } func track(trafficType: String, eventType: String, value: Double) -> Bool { - return false + false } func track(eventType: String) -> Bool { - return false + false } func track(eventType: String, value: Double) -> Bool { - return false + false } func setAttribute(name: String, value: Any) -> Bool { - return false + false } func getAttribute(name: String) -> Any? { - return false + false } func setAttributes(_ values: [String: Any]) -> Bool { - return false + false } func getAttributes() -> [String: Any]? { @@ -100,11 +91,11 @@ class FailedClient: SplitClient { } func removeAttribute(name: String) -> Bool { - return false + false } func clearAttributes() -> Bool { - return false + false } func getTreatmentsByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: String] { @@ -139,33 +130,30 @@ class FailedClient: SplitClient { return [:] } - func setUserConsent(enabled: Bool) { - } + func setUserConsent(enabled: Bool) {} - func flush() { - } + func flush() {} - func destroy() { - } + func destroy() {} func destroy(completion: (() -> Void)?) { completion?() } func track(trafficType: String, eventType: String, properties: [String: Any]?) -> Bool { - return false + false } func track(trafficType: String, eventType: String, value: Double, properties: [String: Any]?) -> Bool { - return false + false } func track(eventType: String, properties: [String: Any]?) -> Bool { - return false + false } func track(eventType: String, value: Double, properties: [String: Any]?) -> Bool { - return false + false } } @@ -175,6 +163,6 @@ class FailedManager: SplitManager { var splitNames: [String] = [] func split(featureName: String) -> SplitView? { - return nil + nil } } diff --git a/Split/Api/LocalhostSplitClient.swift b/Split/Api/LocalhostSplitClient.swift index a2a3f6f6..c2496d08 100644 --- a/Split/Api/LocalhostSplitClient.swift +++ b/Split/Api/LocalhostSplitClient.swift @@ -65,27 +65,27 @@ public final class LocalhostSplitClient: NSObject, SplitClient { } public func getTreatment(_ split: String, attributes: [String: Any]?) -> String { - return getTreatmentWithConfig(split).treatment + getTreatmentWithConfig(split).treatment } public func getTreatment(_ split: String) -> String { - return getTreatment(split, attributes: nil) + getTreatment(split, attributes: nil) } public func getTreatment(_ split: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> String { - return getTreatmentWithConfig(split, attributes: attributes, evaluationOptions: evaluationOptions).treatment + getTreatmentWithConfig(split, attributes: attributes, evaluationOptions: evaluationOptions).treatment } public func getTreatments(splits: [String], attributes: [String: Any]?) -> [String: String] { - return getTreatmentsWithConfig(splits: splits, attributes: nil).mapValues({ $0.treatment }) + getTreatmentsWithConfig(splits: splits, attributes: nil).mapValues({ $0.treatment }) } public func getTreatments(splits: [String], attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: String] { - return getTreatmentsWithConfig(splits: splits, attributes: attributes, evaluationOptions: evaluationOptions).mapValues({ $0.treatment }) + getTreatmentsWithConfig(splits: splits, attributes: attributes, evaluationOptions: evaluationOptions).mapValues({ $0.treatment }) } public func getTreatmentWithConfig(_ split: String) -> SplitResult { - return getTreatmentWithConfig(split, attributes: nil) + getTreatmentWithConfig(split, attributes: nil) } public func getTreatmentWithConfig(_ split: String, attributes: [String: Any]?) -> SplitResult { @@ -102,7 +102,7 @@ public final class LocalhostSplitClient: NSObject, SplitClient { } public func getTreatmentWithConfig(_ split: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> SplitResult { - return getTreatmentWithConfig(split, attributes: attributes) + getTreatmentWithConfig(split, attributes: attributes) } public func getTreatmentsWithConfig(splits: [String], attributes: [String: Any]?) -> [String: SplitResult] { @@ -144,11 +144,9 @@ public final class LocalhostSplitClient: NSObject, SplitClient { private func on(eventWithMetadata event: SplitEventWithMetadata, runInBackground: Bool, queue: DispatchQueue?, execute action: @escaping SplitAction) { guard let factory = clientManger?.splitFactory else { return } + if let eventsManager = self.eventsManager { - let task = SplitEventActionTask(action: action, event: event.type, - runInBackground: runInBackground, - factory: factory, - queue: queue) + let task = SplitEventActionTask(action: action, event: event.type, runInBackground: runInBackground, factory: factory, queue: queue) eventsManager.register(event: event, task: task) } } @@ -156,52 +154,48 @@ public final class LocalhostSplitClient: NSObject, SplitClient { private func on(eventWithMetadata event: SplitEventWithMetadata, runInBackground: Bool, queue: DispatchQueue?, execute action: @escaping SplitActionWithMetadata) { guard let factory = clientManger?.splitFactory else { return } + if let eventsManager = self.eventsManager { - let task = SplitEventActionTask(action: action, event: event.type, - runInBackground: runInBackground, - factory: factory, - queue: queue) + let task = SplitEventActionTask(action: action, event: event.type, runInBackground: runInBackground, factory: factory, queue: queue) eventsManager.register(event: event, task: task) } } public func track(trafficType: String, eventType: String) -> Bool { - return true + true } public func track(trafficType: String, eventType: String, value: Double) -> Bool { - return true + true } public func track(eventType: String) -> Bool { - return true + true } public func track(eventType: String, value: Double) -> Bool { - return true + true } public func track(trafficType: String, eventType: String, properties: [String: Any]?) -> Bool { - return true + true } public func track(trafficType: String, eventType: String, value: Double, properties: [String: Any]?) -> Bool { - return true + true } public func track(eventType: String, properties: [String: Any]?) -> Bool { - return true + true } public func track(eventType: String, value: Double, properties: [String: Any]?) -> Bool { - return true + true } - public func setUserConsent(enabled: Bool) { - } + public func setUserConsent(enabled: Bool) {} - public func flush() { - } + public func flush() {} public func destroy() { splitsStorage.destroy() @@ -217,63 +211,61 @@ public final class LocalhostSplitClient: NSObject, SplitClient { extension LocalhostSplitClient { public func setAttribute(name: String, value: Any) -> Bool { - return true + true } public func getAttribute(name: String) -> Any? { - return nil + nil } public func setAttributes(_ values: [String: Any]) -> Bool { - return true + true } public func getAttributes() -> [String: Any]? { - return nil + nil } public func removeAttribute(name: String) -> Bool { - return true + true } public func clearAttributes() -> Bool { - return true + true } } // MARK: TreatmentBySets Feature extension LocalhostSplitClient { public func getTreatmentsByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: String] { - return [String: String]() + [String: String]() } public func getTreatmentsByFlagSets(_ flagSets: [String], attributes: [String: Any]?) -> [String: String] { - return [String: String]() + [String: String]() } public func getTreatmentsWithConfigByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: SplitResult] { - return [String: SplitResult]() + [String: SplitResult]() } public func getTreatmentsWithConfigByFlagSets(_ flagSets: [String], attributes: [String: Any]?) -> [String: SplitResult] { - return [String: SplitResult]() + [String: SplitResult]() } public func getTreatmentsByFlagSet(_ flagSet: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: String] { - return [String: String]() + [String: String]() } public func getTreatmentsByFlagSets(_ flagSets: [String], attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: String] { - return [String: String]() + [String: String]() } - public func getTreatmentsWithConfigByFlagSet(_ flagSet: String, - attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: SplitResult] { - return [String: SplitResult]() + public func getTreatmentsWithConfigByFlagSet(_ flagSet: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: SplitResult] { + [String: SplitResult]() } - public func getTreatmentsWithConfigByFlagSets(_ flagSets: [String], - attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: SplitResult] { - return [String: SplitResult]() + public func getTreatmentsWithConfigByFlagSets(_ flagSets: [String], attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: SplitResult] { + [String: SplitResult]() } } diff --git a/Split/Api/SplitClient.swift b/Split/Api/SplitClient.swift index 3aff37ad..2ff8a0f7 100644 --- a/Split/Api/SplitClient.swift +++ b/Split/Api/SplitClient.swift @@ -1,20 +1,13 @@ -// -// SplitClient.swift -// Split -// // Created by Brian Sztamfater on 18/9/17. -// -// import Foundation @objc public protocol SplitClient { - // MARK: Evaluation feature + // MARK: Evaluation func getTreatment(_ split: String, attributes: [String: Any]?) -> String func getTreatment(_ split: String) -> String - @objc(getTreatmentsForSplits:attributes:) func getTreatments(splits: [String], - attributes: [String: Any]?) -> [String: String] + @objc(getTreatmentsForSplits:attributes:) func getTreatments(splits: [String], attributes: [String: Any]?) -> [String: String] func getTreatmentWithConfig(_ split: String) -> SplitResult func getTreatmentWithConfig(_ split: String, attributes: [String: Any]?) -> SplitResult @@ -22,27 +15,27 @@ import Foundation @objc(getTreatmentsWithConfigForSplits:attributes:) func getTreatmentsWithConfig(splits: [String], attributes: [String: Any]?) -> [String: SplitResult] - // MARK: Evaluation with Properties + // MARK: With Properties func getTreatment(_ split: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> String - @objc(getTreatmentsForSplits:attributes:evaluationOptions:) func getTreatments(splits: [String], - attributes: [String: Any]?, - evaluationOptions: EvaluationOptions?) -> [String: String] + @objc(getTreatmentsForSplits:attributes:evaluationOptions:) + func getTreatments(splits: [String], attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: String] func getTreatmentWithConfig(_ split: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> SplitResult @objc(getTreatmentsWithConfigForSplits:attributes:evaluationOptions:) func getTreatmentsWithConfig(splits: [String], attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: SplitResult] + // MARK: Customer listeners func on(event: SplitEvent, execute action: @escaping SplitAction) func on(event: SplitEvent, executeWithMetadata: @escaping SplitActionWithMetadata) -> Void func on(event: SplitEvent, runInBackground: Bool, execute action: @escaping SplitAction) func on(event: SplitEvent, queue: DispatchQueue, execute action: @escaping SplitAction) - // MARK: Track feature + // MARK: Tracking func track(trafficType: String, eventType: String) -> Bool func track(trafficType: String, eventType: String, value: Double) -> Bool func track(eventType: String) -> Bool func track(eventType: String, value: Double) -> Bool - // MARK: Persistent attributes feature + // MARK: Persistence /// Creates or updates the value for the given attribute func setAttribute(name: String, value: Any) -> Bool @@ -62,34 +55,31 @@ import Foundation /// Clears all attributes stored in the SDK. func clearAttributes() -> Bool - // MARK: Client lifecycle + // MARK: Lifecycle func flush() func destroy() func destroy(completion: (() -> Void)?) - @objc(trackWithTrafficType:eventType:properties:) func track(trafficType: String, - eventType: String, - properties: [String: Any]?) -> Bool + // MARK: With Properties + @objc(trackWithTrafficType:eventType:properties:) + func track(trafficType: String, eventType: String, properties: [String: Any]?) -> Bool - @objc(trackWithTrafficType:eventType:value:properties:) func track(trafficType: String, - eventType: String, - value: Double, - properties: [String: Any]?) -> Bool + @objc(trackWithTrafficType:eventType:value:properties:) + func track(trafficType: String, eventType: String, value: Double, properties: [String: Any]?) -> Bool - @objc(trackWithEventType:properties:) func track(eventType: String, - properties: [String: Any]?) -> Bool + @objc(trackWithEventType:properties:) + func track(eventType: String, properties: [String: Any]?) -> Bool - @objc(trackWithEventType:value:properties:) func track(eventType: String, - value: Double, - properties: [String: Any]?) -> Bool + @objc(trackWithEventType:value:properties:) + func track(eventType: String, value: Double, properties: [String: Any]?) -> Bool - // MARK: Evaluation with flagsets + // MARK: With Flagsets func getTreatmentsByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: String] func getTreatmentsByFlagSets(_ flagSets: [String], attributes: [String: Any]?) -> [String: String] func getTreatmentsWithConfigByFlagSet(_ flagSet: String, attributes: [String: Any]?) -> [String: SplitResult] func getTreatmentsWithConfigByFlagSets(_ flagSets: [String], attributes: [String: Any]?) -> [String: SplitResult] - // MARK: Evaluation with flagsets and properties + // MARK: With flagsets and properties func getTreatmentsByFlagSet(_ flagSet: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: String] func getTreatmentsByFlagSets(_ flagSets: [String], attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: String] func getTreatmentsWithConfigByFlagSet(_ flagSet: String, attributes: [String: Any]?, evaluationOptions: EvaluationOptions?) -> [String: SplitResult] diff --git a/Split/Engine/DefaultTreatmentManager.swift b/Split/Engine/DefaultTreatmentManager.swift index 73594b32..71619152 100644 --- a/Split/Engine/DefaultTreatmentManager.swift +++ b/Split/Engine/DefaultTreatmentManager.swift @@ -337,8 +337,8 @@ extension DefaultTreatmentManager { } private func isSdkReady() -> Bool { - return eventsManager.eventAlreadyTriggered(event: SplitEvent.sdkReadyFromCache) || - eventsManager.eventAlreadyTriggered(event: SplitEvent.sdkReady) + return eventsManager.eventAlreadyTriggered(event: .sdkReadyFromCache) || + eventsManager.eventAlreadyTriggered(event: .sdkReady) } private func checkAndLogIfDestroyed(logTag: String) -> Bool { diff --git a/Split/Engine/Evaluator.swift b/Split/Engine/Evaluator.swift index 8d209810..5deaf4fa 100644 --- a/Split/Engine/Evaluator.swift +++ b/Split/Engine/Evaluator.swift @@ -6,49 +6,10 @@ // import Foundation -// swiftlint:disable function_body_length -struct EvaluationResult { - var treatment: String - var label: String - var changeNumber: Int64? - var configuration: String? - var impressionsDisabled: Bool - - init(treatment: String, label: String, changeNumber: Int64? = nil, configuration: String? = nil, - impressionsDisabled: Bool = false) { - self.treatment = treatment - self.label = label - self.changeNumber = changeNumber - self.configuration = configuration - self.impressionsDisabled = impressionsDisabled - } -} - -struct EvalValues { - let matchValue: Any? - let matchingKey: String - let bucketingKey: String? - let attributes: [String: Any]? - init(matchValue: Any?, matchingKey: String, bucketingKey: String? = nil, attributes: [String: Any]? = nil) { - self.matchValue = matchValue - self.matchingKey = matchingKey - self.bucketingKey = bucketingKey - self.attributes = attributes - } -} - -// Components needed -struct EvalContext { - let evaluator: Evaluator? - let mySegmentsStorage: MySegmentsStorage? - let myLargeSegmentsStorage: MySegmentsStorage? - let ruleBasedSegmentsStorage: RuleBasedSegmentsStorage? -} protocol Evaluator { - func evalTreatment(matchingKey: String, bucketingKey: String?, - splitName: String, attributes: [String: Any]?) throws -> EvaluationResult + func evalTreatment(matchingKey: String, bucketingKey: String?, splitName: String, attributes: [String: Any]?) throws -> EvaluationResult } class DefaultEvaluator: Evaluator { @@ -184,3 +145,42 @@ private extension Split { return self.impressionsDisabled ?? false } } + +//MARK: Components needed +struct EvaluationResult { + var treatment: String + var label: String + var changeNumber: Int64? + var configuration: String? + var impressionsDisabled: Bool + + init(treatment: String, label: String, changeNumber: Int64? = nil, configuration: String? = nil, + impressionsDisabled: Bool = false) { + self.treatment = treatment + self.label = label + self.changeNumber = changeNumber + self.configuration = configuration + self.impressionsDisabled = impressionsDisabled + } +} + +struct EvalValues { + let matchValue: Any? + let matchingKey: String + let bucketingKey: String? + let attributes: [String: Any]? + + init(matchValue: Any?, matchingKey: String, bucketingKey: String? = nil, attributes: [String: Any]? = nil) { + self.matchValue = matchValue + self.matchingKey = matchingKey + self.bucketingKey = bucketingKey + self.attributes = attributes + } +} + +struct EvalContext { + let evaluator: Evaluator? + let mySegmentsStorage: MySegmentsStorage? + let myLargeSegmentsStorage: MySegmentsStorage? + let ruleBasedSegmentsStorage: RuleBasedSegmentsStorage? +} diff --git a/Split/Events/EventMetadataType.swift b/Split/Events/EventMetadataType.swift index da441c02..fa9660d1 100644 --- a/Split/Events/EventMetadataType.swift +++ b/Split/Events/EventMetadataType.swift @@ -3,8 +3,8 @@ import Foundation @objc public class EventMetadata: NSObject { - var type: EventMetadataType - var data: String = "" + public var type: EventMetadataType + public var data: String = "" init(type: EventMetadataType, data: String) { self.type = type @@ -12,7 +12,7 @@ import Foundation } } -@objc enum EventMetadataType: Int { +@objc public enum EventMetadataType: Int { case FLAGS_UPDATED case FLAGS_KILLED case SEGMENTS_UPDATED diff --git a/Split/Events/SplitEventsManager.swift b/Split/Events/SplitEventsManager.swift index 6581eaa8..10cf9609 100644 --- a/Split/Events/SplitEventsManager.swift +++ b/Split/Events/SplitEventsManager.swift @@ -176,7 +176,7 @@ class DefaultSplitEventsManager: SplitEventsManager { isTriggered(internal: .mySegmentsLoadedFromCache), isTriggered(internal: .myLargeSegmentsLoadedFromCache), isTriggered(internal: .attributesLoadedFromCache) { - trigger(event: SplitEvent.sdkReadyFromCache) + trigger(event: .sdkReadyFromCache) } case .splitKilledNotification: if isTriggered(external: .sdkReady) { @@ -185,7 +185,7 @@ class DefaultSplitEventsManager: SplitEventsManager { } case .sdkReadyTimeoutReached: if !isTriggered(external: .sdkReady) { - trigger(event: SplitEvent.sdkReadyTimedOut) + trigger(event: .sdkReadyTimedOut) } } } diff --git a/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift b/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift index c8ec78ae..4b4b015d 100644 --- a/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift +++ b/Split/Network/Streaming/SyncSegmentsUpdateWorker.swift @@ -110,7 +110,7 @@ class SegmentsUpdateWorker: UpdateWorker { if segments.count > newSegments.count { mySegmentsStorage.set(SegmentChange(segments: newSegments.asArray()), forKey: key) - synchronizer.notifyUpdate(forKey: key) + synchronizer.notifyUpdate(forKey: key, EventMetadata(type: .SEGMENTS_UPDATED, data: newSegments.asArray().joined(separator: ","))) telemetryProducer?.recordUpdatesFromSse(type: resource) } } @@ -128,7 +128,7 @@ class SegmentsUpdateWorker: UpdateWorker { if oldSegments.count < newSegments.count { mySegmentsStorage.set(SegmentChange(segments: newSegments.asArray()), forKey: userKey) - synchronizer.notifyUpdate(forKey: userKey) + synchronizer.notifyUpdate(forKey: userKey, EventMetadata(type: .SEGMENTS_UPDATED, data: newSegments.asArray().joined(separator: ","))) telemetryProducer?.recordUpdatesFromSse(type: .mySegments) } return @@ -171,7 +171,7 @@ class SegmentsUpdateWorker: UpdateWorker { protocol SegmentsSynchronizerWrapper { func fetch(byKey: String, changeNumbers: SegmentsChangeNumber, delay: Int64) - func notifyUpdate(forKey: String) + func notifyUpdate(forKey: String, _ metadata: EventMetadata?) } class MySegmentsSynchronizerWrapper: SegmentsSynchronizerWrapper { @@ -185,12 +185,13 @@ class MySegmentsSynchronizerWrapper: SegmentsSynchronizerWrapper { synchronizer.forceMySegmentsSync(forKey: key, changeNumbers: changeNumbers, delay: delay) } - func notifyUpdate(forKey key: String) { - synchronizer.notifySegmentsUpdated(forKey: key) + func notifyUpdate(forKey key: String, _ metadata: EventMetadata? = nil) { + synchronizer.notifySegmentsUpdated(forKey: key, metadata) } } class MyLargeSegmentsSynchronizerWrapper: SegmentsSynchronizerWrapper { + private let synchronizer: Synchronizer init(synchronizer: Synchronizer) { @@ -201,8 +202,8 @@ class MyLargeSegmentsSynchronizerWrapper: SegmentsSynchronizerWrapper { synchronizer.forceMySegmentsSync(forKey: key, changeNumbers: changeNumbers, delay: delay) } - func notifyUpdate(forKey key: String) { - synchronizer.notifyLargeSegmentsUpdated(forKey: key) + func notifyUpdate(forKey key: String, _ metadata: EventMetadata? = nil) { + synchronizer.notifyLargeSegmentsUpdated(forKey: key, metadata) } } diff --git a/Split/Network/Streaming/SyncUpdateWorker.swift b/Split/Network/Streaming/SyncUpdateWorker.swift index 11272464..fac6f5a7 100644 --- a/Split/Network/Streaming/SyncUpdateWorker.swift +++ b/Split/Network/Streaming/SyncUpdateWorker.swift @@ -175,14 +175,16 @@ class SplitsUpdateWorker: UpdateWorker { Logger.v("RBS update received: \(change)") - let processedChange = ruleBasedSegmentsChangeProcessor.process(change) - - if ruleBasedSegmentsStorage.update(toAdd: processedChange.toAdd, - toRemove: processedChange.toRemove, - changeNumber: processedChange.changeNumber) { - synchronizer.notifyFeatureFlagsUpdated(flagsList: []) //TODO: Notify segments updated (new notification method?) + let processedSegments = ruleBasedSegmentsChangeProcessor.process(change) + + if ruleBasedSegmentsStorage.update(toAdd: processedSegments.toAdd, + toRemove: processedSegments.toRemove, + changeNumber: processedSegments.changeNumber) { + var updatedSegments: [String] = processedSegments.activeSegments.compactMap(\.name) + updatedSegments += processedSegments.archivedSegments.compactMap(\.name) + synchronizer.notifyFeatureFlagsUpdated(flagsList: []) //TODO: Make new notify segments updated (new notification method?) } - + telemetryProducer?.recordUpdatesFromSse(type: .splits) return true } catch { diff --git a/Split/Network/Sync/ByKeyFacade.swift b/Split/Network/Sync/ByKeyFacade.swift index 5f7212bd..f33eda13 100644 --- a/Split/Network/Sync/ByKeyFacade.swift +++ b/Split/Network/Sync/ByKeyFacade.swift @@ -19,8 +19,8 @@ protocol ByKeyRegistry { protocol ByKeySynchronizer { func loadMySegmentsFromCache(forKey: String) func loadAttributesFromCache(forKey: String) - func notifyMySegmentsUpdated(forKey: String) - func notifyMyLargeSegmentsUpdated(forKey: String) + func notifyMySegmentsUpdated(forKey: String, _ metadata: EventMetadata?) + func notifyMyLargeSegmentsUpdated(forKey: String, _ metadata: EventMetadata?) func startSync(forKey key: Key) func startPeriodicSync() func stopPeriodicSync() @@ -120,15 +120,15 @@ class DefaultByKeyFacade: ByKeyFacade { byKeyComponents.value(forKey: key)?.mySegmentsSynchronizer.synchronizeMySegments() } - func notifyMySegmentsUpdated(forKey key: String) { + func notifyMySegmentsUpdated(forKey key: String, _ metadata: EventMetadata?) { doInAll(forMatchingKey: key) { group in - group.eventsManager.notifyInternalEvent(.mySegmentsUpdated) + group.eventsManager.notifyInternalEvent(.mySegmentsUpdated, metadata: metadata) } } - func notifyMyLargeSegmentsUpdated(forKey key: String) { + func notifyMyLargeSegmentsUpdated(forKey key: String, _ metadata: EventMetadata? = nil) { doInAll(forMatchingKey: key) { group in - group.eventsManager.notifyInternalEvent(.myLargeSegmentsUpdated) + group.eventsManager.notifyInternalEvent(.myLargeSegmentsUpdated, metadata: metadata) } } @@ -178,9 +178,7 @@ class DefaultByKeyFacade: ByKeyFacade { } } - private func doInAll(forMatchingKey key: String, - action: (ByKeyComponentGroup) -> Void) { - + private func doInAll(forMatchingKey key: String, action: (ByKeyComponentGroup) -> Void) { byKeyComponents.values(forMatchingKey: key).forEach { group in action(group) } diff --git a/Split/Network/Sync/FeatureFlagsSynchronizer.swift b/Split/Network/Sync/FeatureFlagsSynchronizer.swift index 314dc9ad..3f4c8c79 100644 --- a/Split/Network/Sync/FeatureFlagsSynchronizer.swift +++ b/Split/Network/Sync/FeatureFlagsSynchronizer.swift @@ -78,7 +78,7 @@ class DefaultFeatureFlagsSynchronizer: FeatureFlagsSynchronizer { return } - let splitsStorage = self.storageContainer.splitsStorage + let splitsStorage = storageContainer.splitsStorage DispatchQueue.general.async { let start = Date.nowMillis() self.filterSplitsInCache() diff --git a/Split/Network/Sync/Synchronizer.swift b/Split/Network/Sync/Synchronizer.swift index ec789a03..631e0252 100644 --- a/Split/Network/Sync/Synchronizer.swift +++ b/Split/Network/Sync/Synchronizer.swift @@ -31,8 +31,8 @@ protocol Synchronizer: ImpressionLogger { func stopRecordingTelemetry() func pushEvent(event: EventDTO) func notifyFeatureFlagsUpdated(flagsList: [String]) - func notifySegmentsUpdated(forKey key: String) - func notifyLargeSegmentsUpdated(forKey key: String) + func notifySegmentsUpdated(forKey key: String, _ metadata: EventMetadata?) + func notifyLargeSegmentsUpdated(forKey key: String, _ metadata: EventMetadata?) func notifySplitKilled() func pause() func resume() @@ -211,12 +211,12 @@ class DefaultSynchronizer: Synchronizer { featureFlagsSynchronizer.notifyUpdated(flagsList: flagsList) } - func notifySegmentsUpdated(forKey key: String) { - byKeySynchronizer.notifyMySegmentsUpdated(forKey: key) + func notifySegmentsUpdated(forKey key: String, _ metadata: EventMetadata? = nil) { + byKeySynchronizer.notifyMySegmentsUpdated(forKey: key, metadata) } - func notifyLargeSegmentsUpdated(forKey key: String) { - byKeySynchronizer.notifyMyLargeSegmentsUpdated(forKey: key) + func notifyLargeSegmentsUpdated(forKey key: String, _ metadata: EventMetadata? = nil) { + byKeySynchronizer.notifyMyLargeSegmentsUpdated(forKey: key, metadata) } func notifySplitKilled() { diff --git a/SplitTests/Fake/InternalSplitClientStub.swift b/SplitTests/Fake/InternalSplitClientStub.swift index 2d54d6e3..1abe9452 100644 --- a/SplitTests/Fake/InternalSplitClientStub.swift +++ b/SplitTests/Fake/InternalSplitClientStub.swift @@ -95,86 +95,77 @@ class InternalSplitClientStub: InternalSplitClient { return ["": SplitResult(treatment: SplitConstants.control)] } - func on(event: SplitEvent, queue: DispatchQueue, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, queue: DispatchQueue, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, runInBackground: Bool, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, runInBackground: Bool, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, executeWithMetadata: @escaping SplitActionWithMetadata) { - } + func on(event: SplitEvent, executeWithMetadata: @escaping SplitActionWithMetadata) {} func track(trafficType: String, eventType: String) -> Bool { - return true + true } func track(trafficType: String, eventType: String, value: Double) -> Bool { - return true + true } func track(eventType: String) -> Bool { - return true + true } func track(eventType: String, value: Double) -> Bool { - return true + true } func track(trafficType: String, eventType: String, properties: [String: Any]?) -> Bool { - return true + true } func track(trafficType: String, eventType: String, value: Double, properties: [String: Any]?) -> Bool { - return true + true } func track(eventType: String, properties: [String: Any]?) -> Bool { - return true + true } func track(eventType: String, value: Double, properties: [String: Any]?) -> Bool { - return true + true } func setAttribute(name: String, value: Any) -> Bool { - return true + true } func getAttribute(name: String) -> Any? { - return nil + nil } func setAttributes(_ values: [String: Any]) -> Bool { - return true + true } func getAttributes() -> [String: Any]? { - return nil + nil } func removeAttribute(name: String) -> Bool { - return true + true } func clearAttributes() -> Bool { - return true + true } - func flush() { - } + func flush() {} - func destroy() { - } - - func destroy(completion: (() -> Void)?) { - } + func destroy() {} - func on(event: SplitEvent, executeTask: SplitEventTask) { + func destroy(completion: (() -> Void)?) {} - } + func on(event: SplitEvent, executeTask: SplitEventTask) {} private func createControlTreatmentsDictionary(splits: [String]) -> [String: T] where T: Any { var result = [String: T]() diff --git a/SplitTests/Fake/SplitClientStub.swift b/SplitTests/Fake/SplitClientStub.swift index 5927d9a0..26453c68 100644 --- a/SplitTests/Fake/SplitClientStub.swift +++ b/SplitTests/Fake/SplitClientStub.swift @@ -83,83 +83,75 @@ class SplitClientStub: SplitClient { return ["feature": SplitResult(treatment: SplitConstants.control)] } - func on(event: SplitEvent, queue: DispatchQueue, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, queue: DispatchQueue, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, runInBackground: Bool, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, runInBackground: Bool, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, runInBackground: Bool, queue: DispatchQueue?, execute action: @escaping SplitAction) { - } + func on(event: SplitEvent, runInBackground: Bool, queue: DispatchQueue?, execute action: @escaping SplitAction) {} - func on(event: SplitEvent, executeWithMetadata: @escaping SplitActionWithMetadata) { - } + func on(event: SplitEvent, executeWithMetadata: @escaping SplitActionWithMetadata) {} func track(trafficType: String, eventType: String) -> Bool { - return true + true } func track(trafficType: String, eventType: String, value: Double) -> Bool { - return true + true } func track(eventType: String) -> Bool { - return true + true } func track(eventType: String, value: Double) -> Bool { - return true + true } func track(trafficType: String, eventType: String, properties: [String:Any]?) -> Bool { - return true + true } func track(trafficType: String, eventType: String, value: Double, properties: [String:Any]?) -> Bool { - return true + true } func track(eventType: String, properties: [String:Any]?) -> Bool { - return true + true } func track(eventType: String, value: Double, properties: [String:Any]?) -> Bool { - return true + true } func setAttribute(name: String, value: Any) -> Bool { - return true + true } func getAttribute(name: String) -> Any? { - return nil + nil } func setAttributes(_ values: [String: Any]) -> Bool { - return true + true } func getAttributes() -> [String: Any]? { - return nil + nil } func removeAttribute(name: String) -> Bool { - return true + true } func clearAttributes() -> Bool { - return true + true } - func flush() { - } + func flush() {} - func destroy() { - } + func destroy() {} - func destroy(completion: (() -> Void)?) { - } + func destroy(completion: (() -> Void)?) {} }