class LaunchDarkly::FileDataSourceImpl
@private
Public Class Methods
new(feature_store, logger, options={})
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 127 def initialize(feature_store, logger, options={}) @feature_store = feature_store @logger = logger @paths = options[:paths] || [] if @paths.is_a? String @paths = [ @paths ] end @auto_update = options[:auto_update] if @auto_update && LaunchDarkly.have_listen? && !options[:force_polling] # force_polling is used only for tests # We have seen unreliable behavior in the 'listen' gem in JRuby 9.1 (https://github.com/guard/listen/issues/449). # Therefore, on that platform we'll fall back to file polling instead. if defined?(JRUBY_VERSION) && JRUBY_VERSION.start_with?("9.1.") @use_listen = false else @use_listen = true end end @poll_interval = options[:poll_interval] || 1 @initialized = Concurrent::AtomicBoolean.new(false) @ready = Concurrent::Event.new end
Public Instance Methods
initialized?()
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 149 def initialized? @initialized.value end
start()
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 153 def start ready = Concurrent::Event.new # We will return immediately regardless of whether the file load succeeded or failed - # the difference can be detected by checking "initialized?" ready.set load_all if @auto_update # If we're going to watch files, then the start event will be set the first time we get # a successful load. @listener = start_listener end ready end
stop()
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 171 def stop @listener.stop if !@listener.nil? end
Private Instance Methods
add_item(all_data, kind, item)
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 226 def add_item(all_data, kind, item) items = all_data[kind] raise ArgumentError, "Received unknown item kind #{kind} in add_data" if items.nil? # shouldn't be possible since we preinitialize the hash key = item[:key].to_sym if !items[key].nil? raise ArgumentError, "#{kind[:namespace]} key \"#{item[:key]}\" was used more than once" end items[key] = item end
load_all()
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 177 def load_all all_data = { FEATURES => {}, SEGMENTS => {} } @paths.each do |path| begin load_file(path, all_data) rescue => exn Util.log_exception(@logger, "Unable to load flag data from \"#{path}\"", exn) return end end @feature_store.init(all_data) @initialized.make_true end
load_file(path, all_data)
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 194 def load_file(path, all_data) parsed = parse_content(IO.read(path)) (parsed[:flags] || {}).each do |key, flag| 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)) end (parsed[:segments] || {}).each do |key, segment| add_item(all_data, SEGMENTS, segment) end end
make_flag_with_value(key, value)
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 236 def make_flag_with_value(key, value) { key: key, on: true, fallthrough: { variation: 0 }, variations: [ value ] } end
parse_content(content)
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 207 def parse_content(content) # We can use the Ruby YAML parser for both YAML and JSON (JSON is a subset of YAML and while # not all YAML parsers handle it correctly, we have verified that the Ruby one does, at least # for all the samples of actual flag data that we've tested). symbolize_all_keys(YAML.safe_load(content)) end
start_listener()
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 245 def start_listener resolved_paths = @paths.map { |p| Pathname.new(File.absolute_path(p)).realpath.to_s } if @use_listen start_listener_with_listen_gem(resolved_paths) else FileDataSourcePoller.new(resolved_paths, @poll_interval, self.method(:load_all), @logger) end end
start_listener_with_listen_gem(resolved_paths)
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 254 def start_listener_with_listen_gem(resolved_paths) path_set = resolved_paths.to_set dir_paths = resolved_paths.map{ |p| File.dirname(p) }.uniq opts = { latency: @poll_interval } l = Listen.to(*dir_paths, opts) do |modified, added, removed| paths = modified + added + removed if paths.any? { |p| path_set.include?(p) } load_all end end l.start l end
symbolize_all_keys(value)
click to toggle source
# File lib/ldclient-rb/file_data_source.rb, line 214 def symbolize_all_keys(value) # This is necessary because YAML.load doesn't have an option for parsing keys as symbols, and # the SDK expects all objects to be formatted that way. if value.is_a?(Hash) value.map{ |k, v| [k.to_sym, symbolize_all_keys(v)] }.to_h elsif value.is_a?(Array) value.map{ |v| symbolize_all_keys(v) } else value end end