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

fix: Increment flag & segment versions when reloading from file data source #285

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions lib/ldclient-rb/impl/integrations/file_data_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def initialize(data_store, data_source_update_sink, logger, options={})
@poll_interval = options[:poll_interval] || 1
@initialized = Concurrent::AtomicBoolean.new(false)
@ready = Concurrent::Event.new

@version_lock = Mutex.new
Copy link
Member Author

Choose a reason for hiding this comment

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

This does result in some behavior change.

If you modify a single flag, all of the flags are going to appear to have changed since we are incrementing all of their versions. This is what the Java SDK does.

Copy link
Member

@kinyoklion kinyoklion Jun 6, 2024

Choose a reason for hiding this comment

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

It is probably fine, but I know we have a few different ways this behaves.

Node: Only update the version if it thinks it changed, but the logic may not be the best. Each flag has its own version which increments from wherever it started if it was in the file data.
Dotnet: One shared version number that applies to all flags.

And some that had this previous behavior. Something we may want to write a spec for at some point.

Both are technically things that could happen with a real client.

@last_version = 1
end

def initialized?
Expand Down Expand Up @@ -93,14 +96,22 @@ def load_all
end

def load_file(path, all_data)
version = 1
@version_lock.synchronize {
version = @last_version
@last_version += 1
}

parsed = parse_content(IO.read(path))
(parsed[:flags] || {}).each do |key, flag|
flag[:version] = version
add_item(all_data, FEATURES, flag)
end
(parsed[:flagValues] || {}).each do |key, value|
add_item(all_data, FEATURES, make_flag_with_value(key.to_s, value))
add_item(all_data, FEATURES, make_flag_with_value(key.to_s, value, version))
end
(parsed[:segments] || {}).each do |key, segment|
segment[:version] = version
add_item(all_data, SEGMENTS, segment)
end
end
Expand Down Expand Up @@ -134,10 +145,11 @@ def add_item(all_data, kind, item)
items[key] = Model.deserialize(kind, item)
end

def make_flag_with_value(key, value)
def make_flag_with_value(key, value, version)
{
key: key,
on: true,
version: version,
fallthrough: { variation: 0 },
variations: [ value ],
}
Expand Down