ruby-server-sdk
ruby-server-sdk copied to clipboard
feat: Configurably allow duplicates in FileDataSourceImpl
Related issues
N/A
Describe the solution you've provided
This PR modifies the FileDataSourceImpl
to accept an additional value in the options hash called allow_duplicates
. false
will be used if no value is provided which will cause this to operate exactly as it does prior to this change.
Configuring allow_duplicates
to be true
will not raise an error when flag or segment values are loaded from multiple files and a subsequent file contains a key found in a previous file.
The purpose of this is to allow a notion of a 'local' override during development. A project may have a /config/feature_flags.yml
and a developer adds a flag to it for a feature they are developing. If they want to commit code with this feature, but don't want other developers encountering it yet, they will have to remember to turn the feature off prior to commiting their change.
With this change, a project could have a /config/feature_flags.yml
which contains the flag values other developers should see, and a /config/feature_flags.local.yml
file, ignored by source control and not checked in. As a developer is working on the new feature, they can have it enabled in the .local
file so they can see the feature and work with it, but disabled in the committed file so it does not impact other developers. As the files are processed in the order they are defined, the values defined in subsequent files would take precedence over duplicate values defined in prior files.
Requirements
- [x] I have added test coverage for new or changed functionality
- [x] I have followed the repository's pull request submission guidelines
- [x] I have validated my changes against all supported platform versions
Describe alternatives you've considered
I considered trying to accomplish this via subclassing the FileDataSourceImpl
but it is not really designed for extension based on the amount of private functionality and state that it maintains internally. As such, an upstream change to the implementation itself seemed like the path of least resistance.
Additional context
# Configuration:
options = {
paths: ["config/feature_flags.yml", "config/feature_flags.local.yml"],
auto_update: true,
allow_duplicates: true,
}
data_source = ::LaunchDarkly::Integrations::FileData.data_source(options)
config = ::LaunchDarkly::Config.new(
data_source: data_source,
send_events: false,
)
ld_client = ::LaunchDarkly::LDClient.new(SDK_KEY, config)
# config/feature_flags.yml
flagValues:
flag1: false
flag2: true
flag3: false
# config/feature_flags.local.yml
flag1: true
# Usage
ld_client.variation("flag1", some_context, false) # returns `true` because it is overridden in .local.yml file
ld_client.variation("flag2", some_context, false) # returns `true`
ld_client.variation("flag3", some_context, false) # returns `false`