Skip to content

Commit

Permalink
static storage check, added to demo app and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Calibretto committed Nov 14, 2023
1 parent 359d1d8 commit 3b36877
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
10 changes: 9 additions & 1 deletion ConfidenceDemoApp/ConfidenceDemoApp/ConfidenceDemoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ extension ConfidenceDemoApp {
guard let secret = ProcessInfo.processInfo.environment["CLIENT_SECRET"] else {
return
}

// If we have no cache, then do a fetch first.
var initializationStratgey: InitializationStrategy = .activateAndFetchAsync
if ConfidenceFeatureProvider.isStorageEmpty() {
initializationStratgey = .fetchAndActivate
}

let provider = ConfidenceFeatureProvider
.Builder(credentials: .clientSecret(secret: secret))
.with(initializationStrategy: .activateAndFetchAsync)
.with(initializationStrategy: initializationStratgey)
.build()
// NOTE: Using a random UUID for each app start is not advised and can result in getting stale values.
let ctx = MutableContext(targetingKey: UUID.init().uuidString, structure: MutableStructure())
OpenFeatureAPI.shared.setProvider(provider: provider, initialContext: ctx)
}
Expand Down
2 changes: 1 addition & 1 deletion ConfidenceDemoApp/ConfidenceDemoApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct ContentView: View {
text.text = OpenFeatureAPI
.shared
.getClient()
.getStringValue(key: "hawkflag.color", defaultValue: "ERROR")
.getStringValue(key: "swift-demoapp.color", defaultValue: "ERROR")
if text.text == "Green" {
color.color = .green
} else if text.text == "Yellow" {
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ The evaluation context is the way for the client to specify contextual data that

The `setProvider()` function is synchronous and returns immediately, however this does not mean that the provider is ready to be used. An asynchronous network request to the Confidence backend to fetch all the flags configured for your application must be completed by the provider first. The provider will then emit a _READY_ event indicating you can start resolving flags.

A ultity function is available on the provider to check if the current storage has any values stored - this can be used to determine the best initialization strategy.
```swift
// If we have no cache, then do a fetch first.
var initializationStratgey: InitializationStrategy = .activateAndFetchAsync
if ConfidenceFeatureProvider.isStorageEmpty() {
initializationStratgey = .fetchAndActivate
}
```

To listen for the _READY_ event, you can add an event handler via the `OpenFeatureAPI` shared instance:
```swift
func providerReady(notification: Notification) {
Expand Down
16 changes: 15 additions & 1 deletion Sources/ConfidenceProvider/Cache/DefaultStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class DefaultStorage: Storage {

public func isEmpty() -> Bool {
guard let data = try? read() else {
return false
return true
}

return data.isEmpty
Expand Down Expand Up @@ -97,3 +97,17 @@ public class DefaultStorage: Storage {
components: resolverCacheBundleId, "\(bundleIdentifier)", filePath)
}
}

extension DefaultStorage {
public static func resolverFlagsCache() -> DefaultStorage {
DefaultStorage(filePath: "resolver.flags.cache")
}

public static func resolverApplyCache() -> DefaultStorage {
DefaultStorage(filePath: "resolver.apply.cache")
}

public static func applierFlagsCache() -> DefaultStorage {
DefaultStorage(filePath: "applier.flags.cache")
}
}
22 changes: 15 additions & 7 deletions Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ public class ConfidenceFeatureProvider: FeatureProvider {
}
}

public func isStorageEmpty() -> Bool {
storage.isEmpty()
}

public func onContextSet(
oldContext: OpenFeature.EvaluationContext?,
newContext: OpenFeature.EvaluationContext
Expand Down Expand Up @@ -382,16 +378,28 @@ public class ConfidenceFeatureProvider: FeatureProvider {
}
}

// MARK: Storage

extension ConfidenceFeatureProvider {
public static func isStorageEmpty(
storage: Storage = DefaultStorage.resolverFlagsCache()
) -> Bool {
storage.isEmpty()
}
}

// MARK: Builder

extension ConfidenceFeatureProvider {
public struct Builder {
var options: ConfidenceClientOptions
var session: URLSession?
var localOverrides: [String: LocalOverride] = [:]
var storage: Storage = DefaultStorage(filePath: "resolver.flags.cache")
var storage: Storage = DefaultStorage.resolverFlagsCache()
var cache: ProviderCache?
var flagApplier: (any FlagApplier)?
var initializationStrategy: InitializationStrategy = .fetchAndActivate
var applyStorage: Storage = DefaultStorage(filePath: "resolver.apply.cache")
var applyStorage: Storage = DefaultStorage.resolverApplyCache()

/// Initializes the builder with the given credentails.
///
Expand Down Expand Up @@ -565,7 +573,7 @@ extension ConfidenceFeatureProvider {
flagApplier
?? FlagApplierWithRetries(
httpClient: NetworkClient(region: options.region),
storage: DefaultStorage(filePath: "applier.flags.cache"),
storage: DefaultStorage.applierFlagsCache(),
options: options
)

Expand Down

0 comments on commit 3b36877

Please sign in to comment.