splitclient-rb 2.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.txt +12 -0
  3. data/NEWS +4 -0
  4. data/README.md +45 -11
  5. data/lib/cache/adapters/adapter.rb +23 -0
  6. data/lib/cache/adapters/memory_adapter.rb +46 -0
  7. data/lib/cache/repositories/repository.rb +25 -0
  8. data/lib/cache/repositories/segments_repository.rb +52 -0
  9. data/lib/cache/repositories/splits_repository.rb +51 -0
  10. data/lib/cache/stores/sdk_blocker.rb +47 -0
  11. data/lib/cache/stores/segment_store.rb +71 -0
  12. data/lib/cache/stores/split_store.rb +64 -0
  13. data/lib/engine/api/client.rb +29 -0
  14. data/lib/engine/api/segments.rb +60 -0
  15. data/lib/engine/api/splits.rb +58 -0
  16. data/lib/{splitclient-engine → engine}/evaluator/splitter.rb +0 -0
  17. data/lib/{splitclient-engine → engine}/impressions/impressions.rb +0 -0
  18. data/lib/{splitclient-engine → engine}/matchers/all_keys_matcher.rb +0 -0
  19. data/lib/{splitclient-engine → engine}/matchers/between_matcher.rb +2 -0
  20. data/lib/{splitclient-engine → engine}/matchers/combiners.rb +0 -0
  21. data/lib/{splitclient-engine → engine}/matchers/combining_matcher.rb +1 -1
  22. data/lib/{splitclient-engine → engine}/matchers/equal_to_matcher.rb +0 -0
  23. data/lib/{splitclient-engine → engine}/matchers/greater_than_or_equal_to_matcher.rb +0 -0
  24. data/lib/{splitclient-engine → engine}/matchers/less_than_or_equal_to_matcher.rb +0 -0
  25. data/lib/{splitclient-engine → engine}/matchers/negation_matcher.rb +0 -0
  26. data/lib/{splitclient-engine → engine}/matchers/user_defined_segment_matcher.rb +4 -21
  27. data/lib/{splitclient-engine → engine}/matchers/whitelist_matcher.rb +0 -0
  28. data/lib/{splitclient-engine → engine}/metrics/binary_search_latency_tracker.rb +0 -0
  29. data/lib/{splitclient-engine → engine}/metrics/metrics.rb +0 -0
  30. data/lib/{splitclient-engine → engine}/parser/condition.rb +5 -7
  31. data/lib/{splitclient-engine → engine}/parser/partition.rb +0 -0
  32. data/lib/{splitclient-engine → engine}/parser/split.rb +11 -3
  33. data/lib/{splitclient-engine → engine}/parser/split_adapter.rb +20 -184
  34. data/lib/engine/parser/split_treatment.rb +65 -0
  35. data/lib/{splitclient-engine → engine}/partitions/treatments.rb +0 -0
  36. data/lib/exceptions/sdk_blocker_timeout_expired_exception.rb +4 -0
  37. data/lib/splitclient-rb.rb +31 -23
  38. data/lib/splitclient-rb/split_config.rb +41 -4
  39. data/lib/splitclient-rb/split_factory.rb +50 -20
  40. data/lib/splitclient-rb/version.rb +1 -1
  41. data/splitclient-rb.gemspec +2 -0
  42. metadata +62 -25
  43. data/lib/splitclient-cache/local_store.rb +0 -45
  44. data/lib/splitclient-engine/parser/segment.rb +0 -84
  45. data/lib/splitclient-engine/parser/segment_parser.rb +0 -46
  46. data/lib/splitclient-engine/parser/split_parser.rb +0 -122
@@ -1,45 +0,0 @@
1
- require 'thread_safe'
2
-
3
- module SplitIoClient
4
- # A thread-safe in-memory store suitable for use
5
- # with the Faraday caching HTTP client, uses the
6
- # Threadsafe gem as the underlying cache.
7
- #
8
- class LocalStore
9
- #
10
- # Default constructor
11
- #
12
- # @return [ThreadSafeMemoryStore] a new store
13
- def initialize
14
- @cache = ThreadSafe::Cache.new
15
- end
16
-
17
- #
18
- # Read a value from the cache
19
- # @param key [Object] the cache key
20
- #
21
- # @return [Object] the cache value
22
- def read(key)
23
- @cache[key]
24
- end
25
-
26
- #
27
- # Store a value in the cache
28
- # @param key [Object] the cache key
29
- # @param value [Object] the value to associate with the key
30
- #
31
- # @return [Object] the value
32
- def write(key, value)
33
- @cache[key] = value
34
- end
35
-
36
-
37
- # deletes value from cache by given key
38
- # @param key [Object] the cache key
39
- def delete(key)
40
- @cache[key] = nil
41
- end
42
-
43
- end
44
-
45
- end
@@ -1,84 +0,0 @@
1
- module SplitIoClient
2
-
3
- #
4
- # acts as dto for a segment structure
5
- #
6
- class Segment < NoMethodError
7
- #
8
- # definition of the segment
9
- #
10
- # @returns [object] segment values
11
- attr_accessor :data
12
-
13
- #
14
- # users for the segment
15
- #
16
- # @returns [object] array of user keys
17
- attr_accessor :users
18
-
19
- #
20
- # added users for the segment in a given time
21
- #
22
- # @returns [object] array of user keys that were added after the last segment fetch
23
- attr_accessor :added
24
-
25
- #
26
- # removed users for the segment in a given time
27
- #
28
- # @returns [object] array of user keys that were removed after the last segment fetch
29
- attr_accessor :removed
30
-
31
- def initialize(segment)
32
- @data = segment
33
- @added = @data[:added]
34
- @removed = @data[:removed]
35
- end
36
-
37
- #
38
- # @returns [string] name of the segment
39
- def name
40
- @data[:name]
41
- end
42
-
43
- #
44
- # @returns [int] since value fo the segment
45
- def since
46
- @data[:since]
47
- end
48
-
49
- #
50
- # @returns [int] till value fo the segment
51
- def till
52
- @data[:till]
53
- end
54
-
55
- #
56
- # @return [boolean] true if the condition is empty false otherwise
57
- def is_empty?
58
- @data.empty? ? true : false
59
- end
60
-
61
- #
62
- # updates the array of user keys valid for the segment, it's used after each segment fetch
63
- #
64
- # @param added [object] array of added user keys
65
- # @param removed [object] array of removed user keys
66
- #
67
- # @return [void]
68
- def refresh_users(added, removed)
69
- if @users.nil?
70
- @users = self.added
71
- else
72
- @added = added unless added.empty?
73
- @removed = removed unless removed.empty?
74
- self.removed.each do |r|
75
- @users.delete_if { |u| u == r }
76
- end
77
- self.added.each do |a|
78
- @users << a unless @users.include?(a)
79
- end
80
- end
81
- end
82
- end
83
-
84
- end
@@ -1,46 +0,0 @@
1
- module SplitIoClient
2
- #
3
- # helper class to parse fetched segments
4
- #
5
- class SegmentParser < NoMethodError
6
- #
7
- # segments data
8
- attr_accessor :segments
9
-
10
- #
11
- # since value for segments
12
- attr_accessor :since
13
-
14
- def initialize(logger)
15
- @segments = []
16
- @since = -1
17
- @logger = logger
18
- end
19
-
20
- #
21
- # method to get a segment by name
22
- #
23
- # @param name [string] segment name
24
- #
25
- # @return [object] segment object
26
- def get_segment(name)
27
- @segments.find { |s| s.name == name }
28
- end
29
-
30
- #
31
- # method to get all segment names within the structure
32
- #
33
- # @return [object] array of segment names
34
- def get_segment_names
35
- @segments.map { |seg| seg.name }
36
- end
37
-
38
- #
39
- # @return [boolean] true if the segment parser data is empty false otherwise
40
- def is_empty?
41
- @segments.empty? ? true : false
42
- end
43
-
44
- end
45
-
46
- end
@@ -1,122 +0,0 @@
1
- module SplitIoClient
2
- #
3
- # helper class to parse fetched splits
4
- #
5
- class SplitParser < NoMethodError
6
- #
7
- # since value for splitChanges last fetch
8
- attr_accessor :since
9
-
10
- #
11
- # till value for splitChanges last fetch
12
- attr_accessor :till
13
-
14
- #
15
- # splits data
16
- attr_accessor :splits
17
-
18
- #
19
- # splits segments data
20
- attr_accessor :segments
21
-
22
- def initialize(logger)
23
- @splits = []
24
- @since = -1
25
- @till = -1
26
- @logger = logger
27
- end
28
-
29
- #
30
- # gets all the split names retrived from the endpoint
31
- #
32
- # @return [object] array of split names
33
- def get_split_names
34
- @splits.map { |s| s.name }
35
- end
36
-
37
- #
38
- # @return [boolean] true if the splits content is empty false otherwise
39
- def is_empty?
40
- @splits.empty? ? true : false
41
- end
42
-
43
- #
44
- # gets all the segment names that are used within the retrieved splits
45
- #
46
- # @return [object] array of segment names
47
- def get_used_segments
48
- segment_names = []
49
-
50
- @splits.each { |s|
51
- s.conditions.each { |c|
52
- c.matchers.each { |m|
53
- m[:userDefinedSegmentMatcherData].each { |seg, name|
54
- segment_names << name
55
- } unless m[:userDefinedSegmentMatcherData].nil?
56
- } unless c.matchers.nil?
57
- }
58
- }
59
- segment_names.uniq
60
- end
61
-
62
- #
63
- # gets a split parsed object by name
64
- #
65
- # @param name [string] name of the split
66
- #
67
- # @return split [object] split object
68
- def get_split(name)
69
- @splits.find { |s| s.name == name }
70
- end
71
-
72
- #
73
- # gets the treatment for the given combination of user key and split name
74
- # using all parsed data for the splits
75
- #
76
- # @param id [string] user key
77
- # @param name [string] split name
78
- # @param default_treatment [string] default treatment value to be returned
79
- #
80
- # @return treatment [object] treatment for this user key, split pair
81
- def get_split_treatment(id, name, default_treatment, attributes = nil)
82
- split = get_split(name)
83
- if !split.is_empty? && split.status == 'ACTIVE' && !split.killed?
84
- split.conditions.each do |condit|
85
- unless condit.is_empty?
86
- matcher = get_matcher_type condit
87
- matches = matcher.match? id, attributes
88
- if matches
89
- treatment = Splitter.get_treatment id, split.seed, condit.partitions
90
- result = treatment.nil? ? default_treatment : treatment
91
- return result
92
- end
93
- end
94
- end
95
- elsif !split.is_empty? && split.status == 'ARCHIVED'
96
- return Treatments::CONTROL
97
- end
98
- default_treatment
99
- end
100
-
101
- #
102
- # gets the matcher type from a condition object
103
- #
104
- # @param contidion [object] a condition object
105
- #
106
- # @return matcher [object] the matcher object for the given condition
107
- def get_matcher_type(condit)
108
- matchers = []
109
- condit.matchers.each do |matcher|
110
- matchers << condit.send("matcher_#{matcher[:matcherType].downcase}", {matcher: matcher, segments: @segments})
111
- end
112
- final_matcher = condit.create_condition_matcher matchers
113
-
114
- if final_matcher.nil?
115
- @logger.error('Invalid matcher type')
116
- else
117
- final_matcher
118
- end
119
- end
120
- end
121
-
122
- end