Skip to content

Commit 9a51844

Browse files
authored
feat: Add LDConfig.sendEvents option to disable all events (#414)
1 parent 94b9c2e commit 9a51844

File tree

14 files changed

+81
-24
lines changed

14 files changed

+81
-24
lines changed

ContractTests/Source/Controllers/SdkController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ final class SdkController: RouteCollection {
9292
if let enableCompression = events.enableGzip {
9393
config.enableCompression = enableCompression
9494
}
95+
} else {
96+
config.sendEvents = false
9597
}
9698

9799
if let tags = createInstance.configuration.tags {

LaunchDarkly.xcodeproj/project.pbxproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@
240240
A3599E892A4B4AD400DB5C67 /* Modifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3599E872A4B4AD400DB5C67 /* Modifier.swift */; };
241241
A3599E8A2A4B4AD400DB5C67 /* Modifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3599E872A4B4AD400DB5C67 /* Modifier.swift */; };
242242
A3599E8B2A4B4AD400DB5C67 /* Modifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3599E872A4B4AD400DB5C67 /* Modifier.swift */; };
243+
A35AC5572CD559DE00875751 /* CwlPreconditionTesting in Frameworks */ = {isa = PBXBuildFile; productRef = A3F4A4802CC2F640006EF480 /* CwlPreconditionTesting */; };
243244
A35AD4602A619E45005A8DCB /* SystemCapabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = A35AD45F2A619E45005A8DCB /* SystemCapabilities.swift */; };
244245
A35AD4612A619E45005A8DCB /* SystemCapabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = A35AD45F2A619E45005A8DCB /* SystemCapabilities.swift */; };
245246
A35AD4622A619E45005A8DCB /* SystemCapabilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = A35AD45F2A619E45005A8DCB /* SystemCapabilities.swift */; };
@@ -560,10 +561,10 @@
560561
isa = PBXFrameworksBuildPhase;
561562
buildActionMask = 2147483647;
562563
files = (
564+
A35AC5572CD559DE00875751 /* CwlPreconditionTesting in Frameworks */,
563565
B4903D9E24BD61EF00F087C4 /* Quick in Frameworks */,
564566
B4903D9B24BD61D000F087C4 /* Nimble in Frameworks */,
565567
B4903D9824BD61B200F087C4 /* OHHTTPStubsSwift in Frameworks */,
566-
A3F4A4812CC2F640006EF480 /* CwlPreconditionTesting in Frameworks */,
567568
8354EFCC1F22491C00C05156 /* LaunchDarkly.framework in Frameworks */,
568569
);
569570
runOnlyForDeploymentPostprocessing = 0;

LaunchDarkly/LaunchDarkly/LDClient.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,8 +878,8 @@ public class LDClient {
878878
}
879879

880880
service = self.serviceFactory.makeDarklyServiceProvider(config: config, context: context, envReporter: environmentReporter)
881-
diagnosticReporter = self.serviceFactory.makeDiagnosticReporter(service: service, environmentReporter: environmentReporter)
882-
eventReporter = self.serviceFactory.makeEventReporter(service: service)
881+
diagnosticReporter = self.serviceFactory.makeDiagnosticReporter(config: config, service: service, environmentReporter: environmentReporter)
882+
eventReporter = self.serviceFactory.makeEventReporter(config: config, service: service)
883883
connectionInformation = self.serviceFactory.makeConnectionInformation()
884884
let cachedData = flagCache.getCachedData(cacheKey: context.fullyQualifiedHashedKey(), contextHash: context.contextHash())
885885
flagSynchronizer = self.serviceFactory.makeFlagSynchronizer(streamingMode: config.allowStreamingMode ? config.streamingMode : .polling,
@@ -897,7 +897,7 @@ public class LDClient {
897897

898898
NotificationCenter.default.addObserver(self, selector: #selector(didCloseEventSource), name: Notification.Name(FlagSynchronizer.Constants.didCloseEventSourceName), object: nil)
899899

900-
eventReporter = self.serviceFactory.makeEventReporter(service: service, onSyncComplete: onEventSyncComplete)
900+
eventReporter = self.serviceFactory.makeEventReporter(config: configuration, service: service, onSyncComplete: onEventSyncComplete)
901901
service.resetFlagResponseCache(etag: cachedData.etag)
902902
flagSynchronizer = self.serviceFactory.makeFlagSynchronizer(streamingMode: config.allowStreamingMode ? config.streamingMode : .polling,
903903
pollingInterval: config.flagPollingInterval(runMode: runMode),

LaunchDarkly/LaunchDarkly/LDClientVariation.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,11 @@ extension LDClient {
173173
var result: LDEvaluationDetail<T>
174174
let featureFlag = flagStore.featureFlag(for: flagKey)
175175
if let featureFlag = featureFlag {
176-
featureFlag.prerequisites?.forEach{ prereqFlagKey in
176+
featureFlag.prerequisites?.forEach { prereqFlagKey in
177177
// recurse on prerequisites to emulate prereq evaluations occurring with desirable side effects such as events for prereqs
178178
_ = variationDetailInternal(prereqFlagKey, LDValue.null, needsReason: needsReason, methodName: methodName)
179179
}
180-
180+
181181
if featureFlag.value == .null {
182182
result = LDEvaluationDetail(value: defaultValue, variationIndex: featureFlag.variation, reason: featureFlag.reason)
183183
} else {
@@ -193,7 +193,7 @@ extension LDClient {
193193
os_log("%s Unknown feature flag %s; returning default value", log: config.logger, type: .debug, typeName(and: #function), flagKey.description)
194194
result = LDEvaluationDetail(value: defaultValue, variationIndex: nil, reason: ["kind": "ERROR", "errorKind": "FLAG_NOT_FOUND"])
195195
}
196-
196+
197197
eventReporter.recordFlagEvaluationEvents(flagKey: flagKey,
198198
value: result.value.toLDValue(),
199199
defaultValue: defaultValue.toLDValue(),

LaunchDarkly/LaunchDarkly/Models/FeatureFlag/FlagRequestTracker.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ final class FlagCounter: Encodable {
4444
private(set) var defaultValue: LDValue
4545
private(set) var flagValueCounters: [CounterKey: CounterValue] = [:]
4646
private(set) var contextKinds: Set<String> = Set()
47-
47+
4848
init(defaultValue: LDValue) {
4949
// default value follows a "first one wins" approach where the first evaluation for a flag key sets the default value for the summary events
5050
self.defaultValue = defaultValue

LaunchDarkly/LaunchDarkly/Models/LDConfig.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ public struct LDConfig {
188188
/// The default base url for connecting to streaming service
189189
static let streamUrl = URL(string: "https://clientstream.launchdarkly.com")!
190190

191+
/// The default behavior for the SDK is to send events.
192+
static let sendEvents = true
193+
191194
/// The default maximum number of events the LDClient can store
192195
static let eventCapacity = 100
193196

@@ -305,6 +308,10 @@ public struct LDConfig {
305308
/// The base url for connecting to the streaming service. Do not change unless instructed by LaunchDarkly.
306309
public var streamUrl: URL = Defaults.streamUrl
307310

311+
/// Whether to send events back to LaunchDarkly. This differs from {#offline?} in that it affects
312+
/// only the sending of client-side events, not streaming or polling for events from the server.
313+
public var sendEvents: Bool = Defaults.sendEvents
314+
308315
/// The maximum number of analytics events the LDClient can store. When the LDClient event store reaches the eventCapacity, the SDK discards events until it successfully reports them to LaunchDarkly. (Default: 100)
309316
public var eventCapacity: Int = Defaults.eventCapacity
310317

@@ -532,6 +539,7 @@ extension LDConfig: Equatable {
532539
&& lhs.eventsUrl == rhs.eventsUrl
533540
&& lhs.streamUrl == rhs.streamUrl
534541
&& lhs.eventCapacity == rhs.eventCapacity
542+
&& lhs.sendEvents == rhs.sendEvents
535543
&& lhs.connectionTimeout == rhs.connectionTimeout
536544
&& lhs.eventFlushInterval == rhs.eventFlushInterval
537545
&& lhs.flagPollingInterval == rhs.flagPollingInterval

LaunchDarkly/LaunchDarkly/Networking/DarklyService.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ final class DarklyService: DarklyServiceProvider {
5151
var context: LDContext
5252
let httpHeaders: HTTPHeaders
5353
let diagnosticCache: DiagnosticCaching?
54-
private (set) var serviceFactory: ClientServiceCreating
54+
private(set) var serviceFactory: ClientServiceCreating
5555
private var session: URLSession
5656
var flagRequestEtag: String?
5757

@@ -60,7 +60,7 @@ final class DarklyService: DarklyServiceProvider {
6060
self.context = context
6161
self.serviceFactory = serviceFactory
6262

63-
if !config.mobileKey.isEmpty && !config.diagnosticOptOut {
63+
if !config.mobileKey.isEmpty && !config.diagnosticOptOut && config.sendEvents {
6464
self.diagnosticCache = serviceFactory.makeDiagnosticCache(sdkKey: config.mobileKey)
6565
} else {
6666
self.diagnosticCache = nil

LaunchDarkly/LaunchDarkly/ObjectiveC/ObjcLDConfig.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public final class ObjcLDConfig: NSObject {
5151
get { config.eventFlushInterval }
5252
set { config.eventFlushInterval = newValue }
5353
}
54+
// Whether or not the SDK should send events
55+
@objc public var sendEvents: Bool {
56+
get { config.sendEvents }
57+
set { config.sendEvents = newValue }
58+
}
5459
/// The interval between feature flag requests. Used only for polling mode. (Default: 5 minutes)
5560
@objc public var flagPollingInterval: TimeInterval {
5661
get { config.flagPollingInterval }

LaunchDarkly/LaunchDarkly/ServiceObjects/ClientServiceFactory.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ protocol ClientServiceCreating {
1515
service: DarklyServiceProvider,
1616
onSyncComplete: FlagSyncCompleteClosure?) -> LDFlagSynchronizing
1717
func makeFlagChangeNotifier() -> FlagChangeNotifying
18-
func makeEventReporter(service: DarklyServiceProvider) -> EventReporting
19-
func makeEventReporter(service: DarklyServiceProvider, onSyncComplete: EventSyncCompleteClosure?) -> EventReporting
18+
func makeEventReporter(config: LDConfig, service: DarklyServiceProvider) -> EventReporting
19+
func makeEventReporter(config: LDConfig, service: DarklyServiceProvider, onSyncComplete: EventSyncCompleteClosure?) -> EventReporting
2020
func makeStreamingProvider(url: URL, httpHeaders: [String: String], connectMethod: String, connectBody: Data?, handler: EventHandler, delegate: RequestHeaderTransform?, errorHandler: ConnectionErrorHandler?) -> DarklyStreamingProvider
2121
func makeEnvironmentReporter(config: LDConfig) -> EnvironmentReporting
2222
func makeThrottler(environmentReporter: EnvironmentReporting) -> Throttling
2323
func makeConnectionInformation() -> ConnectionInformation
2424
func makeDiagnosticCache(sdkKey: String) -> DiagnosticCaching
25-
func makeDiagnosticReporter(service: DarklyServiceProvider, environmentReporter: EnvironmentReporting) -> DiagnosticReporting
25+
func makeDiagnosticReporter(config: LDConfig, service: DarklyServiceProvider, environmentReporter: EnvironmentReporting) -> DiagnosticReporting
2626
func makeFlagStore() -> FlagMaintaining
2727
}
2828

@@ -66,12 +66,16 @@ final class ClientServiceFactory: ClientServiceCreating {
6666
FlagChangeNotifier(logger: logger)
6767
}
6868

69-
func makeEventReporter(service: DarklyServiceProvider) -> EventReporting {
70-
makeEventReporter(service: service, onSyncComplete: nil)
69+
func makeEventReporter(config: LDConfig, service: DarklyServiceProvider) -> EventReporting {
70+
makeEventReporter(config: config, service: service, onSyncComplete: nil)
7171
}
7272

73-
func makeEventReporter(service: DarklyServiceProvider, onSyncComplete: EventSyncCompleteClosure? = nil) -> EventReporting {
74-
EventReporter(service: service, onSyncComplete: onSyncComplete)
73+
func makeEventReporter(config: LDConfig, service: DarklyServiceProvider, onSyncComplete: EventSyncCompleteClosure? = nil) -> EventReporting {
74+
if config.sendEvents {
75+
return EventReporter(service: service, onSyncComplete: onSyncComplete)
76+
} else {
77+
return NullEventReporter()
78+
}
7579
}
7680

7781
func makeStreamingProvider(url: URL,
@@ -121,8 +125,12 @@ final class ClientServiceFactory: ClientServiceCreating {
121125
DiagnosticCache(sdkKey: sdkKey)
122126
}
123127

124-
func makeDiagnosticReporter(service: DarklyServiceProvider, environmentReporter: EnvironmentReporting) -> DiagnosticReporting {
125-
DiagnosticReporter(service: service, environmentReporting: environmentReporter)
128+
func makeDiagnosticReporter(config: LDConfig, service: DarklyServiceProvider, environmentReporter: EnvironmentReporting) -> DiagnosticReporting {
129+
if config.sendEvents && !config.diagnosticOptOut {
130+
return DiagnosticReporter(service: service, environmentReporting: environmentReporter)
131+
} else {
132+
return NullDiagnosticReporter()
133+
}
126134
}
127135

128136
func makeFlagStore() -> FlagMaintaining {

LaunchDarkly/LaunchDarkly/ServiceObjects/DiagnosticReporter.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ protocol DiagnosticReporting {
66
func setMode(_ runMode: LDClientRunMode, online: Bool)
77
}
88

9+
class NullDiagnosticReporter: DiagnosticReporting {
10+
func setMode(_ runMode: LDClientRunMode, online: Bool) {
11+
}
12+
}
13+
914
class DiagnosticReporter: DiagnosticReporting {
1015
private let service: DarklyServiceProvider
1116
private let environmentReporting: EnvironmentReporting

0 commit comments

Comments
 (0)