Skip to content

Commit

Permalink
fix feature flag initialization ordering (#236)
Browse files Browse the repository at this point in the history
* reorder analytics initialization after feature flag initialization

* add logging

* Update StatsigInjections.swift

---------

Co-authored-by: Mike <[email protected]>
  • Loading branch information
mike-dydx and mike-dydx committed Aug 22, 2024
1 parent c224399 commit f5efbf2
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ open class AmplitudeTracking: TransformerTracker {

public init(_ apiKey: String) {
self.amplitude = Amplitude.init(configuration: .init(apiKey: apiKey))
Console.shared.log("analytics log | Amplitude initialized")
super.init()
}

Expand Down
18 changes: 12 additions & 6 deletions Shared/CommonAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ open class CommonAppDelegate: ParticlesAppDelegate {

override open func injectFeatures(completion: @escaping () -> Void) {
Console.shared.log("injectFeatures")
// these three injections need to happen before app start
injectStatsigApiKey()
injectFirebase()
injectRating()
injectAmplitude()

// statsig needs to be initialized before FeatureService is initialized
// because FeatureService sets remote to be StatsigFeatureFlagsProvider.shared
// TODO: remove the ordering dependency
injectStatsig()
let compositeFeatureFlags = CompositeFeatureFlagsProvider()
switch Installation.source {
case .debug, .testFlight:
Expand All @@ -60,6 +60,12 @@ open class CommonAppDelegate: ParticlesAppDelegate {
}
compositeFeatureFlags.remote = StatsigFeatureFlagsProvider.shared
FeatureService.shared = compositeFeatureFlags
// at least the amplitude injection needs to happen before app start and after FeatureService is initialized because
// injectAmplitude triggers abacus initialization which looks at dydxBoolFeatureFlags.force_mainnet
// TODO: remove the ordering dependency
injectFirebase()
injectRating()
injectAmplitude()
FeatureService.shared?.activate { /* [weak self] in */
Injection.shared?.injectFeatured(completion: completion)
}
Expand Down Expand Up @@ -118,7 +124,7 @@ open class CommonAppDelegate: ParticlesAppDelegate {
}
}

open func injectStatsigApiKey() {
open func injectStatsig() {
Console.shared.log("injectStatsig")
let environment: StatsigFeatureFlagsProvider.Environment
switch Installation.source {
Expand Down
22 changes: 16 additions & 6 deletions StatsigInjections/StatsigInjections/StatsigInjections.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public final class StatsigFeatureFlagsProvider: NSObject, FeatureFlagsProtocol {

private let apiKey: String
private let userId: String
private let environment: StatsigEnvironment
private let environment: Environment
// ensures feature flag values stay constant throughout the app session after they are used the first time, even if they are initialized to null
private var sessionValues = [String: Availabilty]()

Expand All @@ -28,7 +28,7 @@ public final class StatsigFeatureFlagsProvider: NSObject, FeatureFlagsProtocol {
case unavailable
}

public enum Environment {
public enum Environment: CustomDebugStringConvertible {
case production
case development

Expand All @@ -40,12 +40,21 @@ public final class StatsigFeatureFlagsProvider: NSObject, FeatureFlagsProtocol {
return StatsigEnvironment(tier: .Development)
}
}

public var debugDescription: String {
switch self {
case .production:
return "production"
case .development:
return "development"
}
}
}

public init(apiKey: String, userId: String, environment: Environment) {
self.apiKey = apiKey
self.userId = userId
self.environment = environment.statsigEnvironemnt
self.environment = environment
}

static public var shared: StatsigFeatureFlagsProvider?
Expand All @@ -64,7 +73,7 @@ public final class StatsigFeatureFlagsProvider: NSObject, FeatureFlagsProtocol {
Statsig.start(sdkKey: apiKey, user: StatsigUser(userID: userId), options: StatsigOptions(
initTimeout: nil,
disableCurrentVCLogging: true,
environment: environment,
environment: environment.statsigEnvironemnt,
enableAutoValueUpdate: true,
autoValueUpdateIntervalSec: nil,
overrideStableID: nil,
Expand All @@ -79,16 +88,17 @@ public final class StatsigFeatureFlagsProvider: NSObject, FeatureFlagsProtocol {
userValidationCallback: nil,
customCacheKey: nil,
urlSession: nil)) {[weak self] error in
Console.shared.log("Statsig feature flags initialized")
Console.shared.log("analytics log | Statsig feature flags finished initial fetch")
if let error {
Console.shared.log("Statsig feature flags failed to initialize: \(error)")
Console.shared.log("analytics log | Statsig feature flags finished initial fetch with error: \(error)")
return
}
self?.initializationState = .initializedRemoteLoaded
// intentionally not calling completion here since we do not want ff init to be blocking startup
// this may change if we need FF pre-launch
// completion()
}
Console.shared.log("analytics log | Statsig initialized (local only, async feature flags fetch ongoing) | env: \(environment.debugDescription) | userId: \(userId)")
initializationState = .initializedRemoteLoading
}
completion()
Expand Down

0 comments on commit f5efbf2

Please sign in to comment.