Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remote config client #2

Open
wants to merge 1 commit into
base: move_files
Choose a base branch
from
Open

chore: remote config client #2

wants to merge 1 commit into from

Conversation

crleona
Copy link
Collaborator

@crleona crleona commented Feb 11, 2025

Summary

Remote Configuration Spec
Configs are indefinitely cached locally by config key.
In general, newly fetched configs > cached configs > locally configured options
Plugins can be added at any time and still need to fetch updated remote configs.
We will use time based coalescing to combine requests - any remote config requests
within a window will all be sent within the same http request.
Browser clients currently wait for remote configuration before starting, and will
either need to convert to this model or continue to maintain a separate approach.
We may still need to preflight some keys (ie, request them outisde of this interface)
to enable some packaging like the unified snippet.

public class RemoteConfigClient {

    public typealias RemoteConfig = [String : Any]

    public typealias RemoteConfigCallback = (ConfigKey, RemoteConfig) -> Void

    /*
     * Synchronously returns a config from cache. Useful during setup
     */
    public func cachedConfig(key: ConfigKey) -> RemoteConfig?

    /*
     * Runs the callback every time the given key is updated, optionally doing an additional callback with the cached
     * config if one exists.
     * Useful when requesting a namespace ("sessionReplay"), then listening for changes to specific keys ("sessionReplay.privacyConfig")
     */
    public func listen(key: ConfigKey, returnCached: Bool = true, callback: @escaping RemoteConfigCallback)

    /*
     * Requests updates for the given key, and optionally adds a listener.
     */
    public func requestConfig(key: ConfigKey, returnCached: Bool = true, callback: RemoteConfigCallback? = nil)

    /*
    Refreshes all requested configs NOW.
    Configs should be stored in cache before any listeners are called (ie, listen(key) { config === cachedConfig(key) })
    */
    public func updateConfigs()
}

Simple Usage:

func requestRemoteConfigs() {}
    remoteConfigClient.register("sessionReplay.privacyConfig") { _, config in
        setting1 = config["setting1"]
        setting2 = config["setting2"]
    }
}

More advanced usage:

init() {

    if let cachedConfig = remoteConfigClient.cachedConfig(key: "sessionReplay.privacyConfig") {
        setting1 = config["setting1"]
        setting2 = config["setting2"]
    }

    if let cachedConfig = remoteConfigClient.cachedConfig(key: "sessionReplay.samplingConfig") {
        setting3 = config["setting3"]
        setting4 = config["setting4"]
    }

    remoteConfigClient.listen(key: "sessionReplay.privacyConfig", returnCached: false) { _, config in
        setting1 = config["setting1"]
        setting2 = config["setting2"]
    }

    remoteConfigClient.listen(key: "sessionReplay.samplingConfig", returnCached: false) { _, config in
        setting3 = config["setting3"]
        setting4 = config["setting4"]
    }

    remoteConfigClient.register(key: "sessionReplay")
}

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?: no

Copy link

@sojingle sojingle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants