Class: SplitIoClient::Cache::Repositories::SplitsRepository

Inherits:
SplitIoClient::Cache::Repository show all
Defined in:
lib/splitclient-rb/cache/repositories/splits_repository.rb

Constant Summary collapse

DEFAULT_CONDITIONS_TEMPLATE =
[{
  conditionType: "ROLLOUT",
  matcherGroup: {
      combiner: "AND",
      matchers: [
      {
          keySelector: nil,
          matcherType: "ALL_KEYS",
          negate: false,
          userDefinedSegmentMatcherData: nil,
          whitelistMatcherData: nil,
          unaryNumericMatcherData: nil,
          betweenMatcherData: nil,
          dependencyMatcherData: nil,
          booleanMatcherData: nil,
          stringMatcherData: nil
      }]
  },
  partitions: [
      {
      treatment: "control",
      size: 100
      }
  ],
  label: "targeting rule type unsupported by sdk"
}]
TILL_PREFIX =
'.splits.till'
SPLIT_PREFIX =
'.split.'
READY_PREFIX =
'.splits.ready'

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from SplitIoClient::Cache::Repository

#set_string, #string

Constructor Details

#initialize(config, flag_sets_repository, flag_set_filter, internal_events_queue) ⇒ SplitsRepository

Returns a new instance of SplitsRepository.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 38

def initialize(config, flag_sets_repository, flag_set_filter, internal_events_queue)
  super(config)
  @tt_cache = {}
  @adapter = case @config.cache_adapter.class.to_s
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
    SplitIoClient::Cache::Adapters::CacheAdapter.new(@config)
  else
    @config.cache_adapter
  end
  @flag_sets = flag_sets_repository
  @flag_set_filter = flag_set_filter
  @internal_events_queue = internal_events_queue
  initialize_keys
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter.



7
8
9
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 7

def adapter
  @adapter
end

Instance Method Details

#clearObject



139
140
141
142
143
144
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 139

def clear
  @tt_cache.clear

  @adapter.clear(namespace_key)
  initialize_keys
end

#exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 123

def exists?(name)
  @adapter.exists?(namespace_key(".split.#{name}"))
end

#flag_set_filterObject



187
188
189
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 187

def flag_set_filter
  @flag_set_filter
end

#get_change_numberObject



111
112
113
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 111

def get_change_number
  @adapter.string(namespace_key(TILL_PREFIX))
end

#get_feature_flags_by_sets(flag_sets) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 171

def get_feature_flags_by_sets(flag_sets)
  sets_to_fetch = Array.new
  flag_sets.each do |flag_set|
    unless @flag_sets.flag_set_exist?(flag_set)
      @config.logger.warn("Flag set #{flag_set} is not part of the configured flag set list, ignoring it.")
      next
    end
    sets_to_fetch.push(flag_set)
  end
  @flag_sets.get_flag_sets(flag_sets)
end

#get_split(name) ⇒ Object



71
72
73
74
75
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 71

def get_split(name)
  split = @adapter.string(namespace_key(".split.#{name}"))

  JSON.parse(split, symbolize_names: true) if split
end

#is_flag_set_exist(flag_set) ⇒ Object



183
184
185
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 183

def is_flag_set_exist(flag_set)
  @flag_sets.flag_set_exist?(flag_set)
end

#kill(change_number, split_name, default_treatment) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 146

def kill(change_number, split_name, default_treatment)
  split = get_split(split_name)

  return if split.nil?

  split[:killed] = true
  split[:defaultTreatment] = default_treatment
  split[:changeNumber] = change_number

  @adapter.set_string(namespace_key(".split.#{split_name}"), split.to_json)
  @internal_events_queue.push(
    SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
      SplitIoClient::Engine::Models::SdkInternalEvent::FLAG_KILLED_NOTIFICATION, 
      SplitIoClient::Engine::Models::EventsMetadata.new(
        SplitIoClient::Engine::Models::SdkEventType::FLAG_UPDATE,
        [split_name]
      )
    )
  )
end

#not_ready!Object



131
132
133
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 131

def not_ready!
  @adapter.set_string(namespace_key(READY_PREFIX), -1)
end

#ready!Object



135
136
137
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 135

def ready!
  @adapter.set_string(namespace_key(READY_PREFIX), Time.now.utc.to_i)
end

#ready?Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 127

def ready?
  @adapter.string(namespace_key(READY_PREFIX)).to_i != -1
end

#set_change_number(since) ⇒ Object



107
108
109
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 107

def set_change_number(since)
  @adapter.set_string(namespace_key(TILL_PREFIX), since)
end

#set_segment_names(names) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 115

def set_segment_names(names)
  return if names.nil? || names.empty?

  names.each do |name|
    @adapter.add_to_set(namespace_key('.segments.registered'), name)
  end
end

#split_namesObject

Return an array of Split Names excluding control keys like splits.till



102
103
104
105
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 102

def split_names
  @adapter.find_strings_by_prefix(namespace_key(SPLIT_PREFIX))
    .map { |split| split.gsub(namespace_key(SPLIT_PREFIX), '') }
end

#splits(filtered_names = nil) ⇒ Object



77
78
79
80
81
82
83
84
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 77

def splits(filtered_names=nil)
  symbolize = true
  if filtered_names.nil?
    filtered_names = split_names
    symbolize = false
  end
  get_splits(filtered_names, symbolize)
end

#splits_countObject



167
168
169
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 167

def splits_count
  split_names.length
end

#traffic_type_exists(tt_name) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 86

def traffic_type_exists(tt_name)
  case @adapter
  when SplitIoClient::Cache::Adapters::CacheAdapter
    tt_count = @adapter.string(namespace_key(".trafficType.#{tt_name}"))
    begin
      !tt_count.nil? && Integer(tt_count, 10) > 0
    rescue StandardError => e
      @config.logger.error("Error while parsing Traffic Type count: #{e.message}")
      false
    end
  else
    @tt_cache.key?(tt_name) && @tt_cache[tt_name] > 0
  end
end

#update(to_add, to_delete, new_change_number) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/splitclient-rb/cache/repositories/splits_repository.rb', line 53

def update(to_add, to_delete, new_change_number)
  to_add.each{ |feature_flag| add_feature_flag(feature_flag) }
  to_delete.each{ |feature_flag| remove_feature_flag(feature_flag) }
  set_change_number(new_change_number)

  if to_add.length > 0 || to_delete.length > 0
    @internal_events_queue.push(
      SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
        SplitIoClient::Engine::Models::SdkInternalEvent::FLAGS_UPDATED, 
        SplitIoClient::Engine::Models::EventsMetadata.new(
          SplitIoClient::Engine::Models::SdkEventType::FLAG_UPDATE,
          to_add.map {|flag| flag[:name]} | to_delete.map {|flag| flag[:name]}
        )
      )
    )
  end
end