prefab-cloud-ruby 0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/Gemfile +9 -22
  4. data/Gemfile.lock +88 -160
  5. data/LICENSE.txt +1 -1
  6. data/Rakefile +14 -14
  7. data/VERSION +1 -1
  8. data/lib/prefab/auth_interceptor.rb +25 -0
  9. data/lib/prefab/client.rb +34 -139
  10. data/lib/prefab/config_client.rb +23 -275
  11. data/lib/prefab/config_loader.rb +27 -60
  12. data/lib/prefab/config_resolver.rb +40 -53
  13. data/lib/prefab/noop_cache.rb +13 -0
  14. data/lib/prefab/noop_stats.rb +8 -0
  15. data/lib/prefab/prefab_pb.rb +39 -0
  16. data/lib/prefab/prefab_services_pb.rb +37 -0
  17. data/lib/prefab/ratelimit_client.rb +58 -0
  18. data/lib/prefab/ratelimit_pb.rb +125 -0
  19. data/lib/prefab/store.rb +29 -0
  20. data/lib/prefab_client.rb +35 -0
  21. metadata +36 -198
  22. data/.envrc.sample +0 -3
  23. data/.github/workflows/ruby.yml +0 -46
  24. data/.gitmodules +0 -3
  25. data/.rubocop.yml +0 -13
  26. data/.tool-versions +0 -1
  27. data/CHANGELOG.md +0 -169
  28. data/CODEOWNERS +0 -1
  29. data/README.md +0 -94
  30. data/bin/console +0 -21
  31. data/compile_protos.sh +0 -18
  32. data/lib/prefab/config_client_presenter.rb +0 -18
  33. data/lib/prefab/config_value_unwrapper.rb +0 -115
  34. data/lib/prefab/config_value_wrapper.rb +0 -18
  35. data/lib/prefab/context.rb +0 -179
  36. data/lib/prefab/context_shape.rb +0 -20
  37. data/lib/prefab/context_shape_aggregator.rb +0 -65
  38. data/lib/prefab/criteria_evaluator.rb +0 -136
  39. data/lib/prefab/encryption.rb +0 -65
  40. data/lib/prefab/error.rb +0 -6
  41. data/lib/prefab/errors/env_var_parse_error.rb +0 -11
  42. data/lib/prefab/errors/initialization_timeout_error.rb +0 -13
  43. data/lib/prefab/errors/invalid_api_key_error.rb +0 -19
  44. data/lib/prefab/errors/missing_default_error.rb +0 -13
  45. data/lib/prefab/errors/missing_env_var_error.rb +0 -11
  46. data/lib/prefab/errors/uninitialized_error.rb +0 -13
  47. data/lib/prefab/evaluation.rb +0 -52
  48. data/lib/prefab/evaluation_summary_aggregator.rb +0 -87
  49. data/lib/prefab/example_contexts_aggregator.rb +0 -78
  50. data/lib/prefab/exponential_backoff.rb +0 -21
  51. data/lib/prefab/feature_flag_client.rb +0 -42
  52. data/lib/prefab/http_connection.rb +0 -41
  53. data/lib/prefab/internal_logger.rb +0 -16
  54. data/lib/prefab/local_config_parser.rb +0 -151
  55. data/lib/prefab/log_path_aggregator.rb +0 -69
  56. data/lib/prefab/logger_client.rb +0 -264
  57. data/lib/prefab/murmer3.rb +0 -50
  58. data/lib/prefab/options.rb +0 -208
  59. data/lib/prefab/periodic_sync.rb +0 -69
  60. data/lib/prefab/prefab.rb +0 -56
  61. data/lib/prefab/rate_limit_cache.rb +0 -41
  62. data/lib/prefab/resolved_config_presenter.rb +0 -86
  63. data/lib/prefab/time_helpers.rb +0 -7
  64. data/lib/prefab/weighted_value_resolver.rb +0 -42
  65. data/lib/prefab/yaml_config_parser.rb +0 -34
  66. data/lib/prefab-cloud-ruby.rb +0 -57
  67. data/lib/prefab_pb.rb +0 -93
  68. data/prefab-cloud-ruby.gemspec +0 -155
  69. data/test/.prefab.default.config.yaml +0 -2
  70. data/test/.prefab.unit_tests.config.yaml +0 -28
  71. data/test/integration_test.rb +0 -150
  72. data/test/integration_test_helpers.rb +0 -151
  73. data/test/support/common_helpers.rb +0 -180
  74. data/test/support/mock_base_client.rb +0 -42
  75. data/test/support/mock_config_client.rb +0 -19
  76. data/test/support/mock_config_loader.rb +0 -1
  77. data/test/test_client.rb +0 -444
  78. data/test/test_config_client.rb +0 -109
  79. data/test/test_config_loader.rb +0 -117
  80. data/test/test_config_resolver.rb +0 -430
  81. data/test/test_config_value_unwrapper.rb +0 -224
  82. data/test/test_config_value_wrapper.rb +0 -42
  83. data/test/test_context.rb +0 -203
  84. data/test/test_context_shape.rb +0 -50
  85. data/test/test_context_shape_aggregator.rb +0 -147
  86. data/test/test_criteria_evaluator.rb +0 -726
  87. data/test/test_encryption.rb +0 -16
  88. data/test/test_evaluation_summary_aggregator.rb +0 -162
  89. data/test/test_example_contexts_aggregator.rb +0 -238
  90. data/test/test_exponential_backoff.rb +0 -18
  91. data/test/test_feature_flag_client.rb +0 -48
  92. data/test/test_helper.rb +0 -17
  93. data/test/test_integration.rb +0 -58
  94. data/test/test_local_config_parser.rb +0 -147
  95. data/test/test_log_path_aggregator.rb +0 -62
  96. data/test/test_logger.rb +0 -621
  97. data/test/test_logger_initialization.rb +0 -12
  98. data/test/test_options.rb +0 -75
  99. data/test/test_prefab.rb +0 -12
  100. data/test/test_rate_limit_cache.rb +0 -44
  101. data/test/test_weighted_value_resolver.rb +0 -71
@@ -1,208 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- # This class contains all the options that can be passed to the Prefab client.
5
- class Options
6
- attr_reader :api_key
7
- attr_reader :logdev
8
- attr_reader :log_prefix
9
- attr_reader :log_formatter
10
- attr_reader :namespace
11
- attr_reader :prefab_api_url
12
- attr_reader :on_no_default
13
- attr_reader :initialization_timeout_sec
14
- attr_reader :on_init_failure
15
- attr_reader :prefab_config_override_dir
16
- attr_reader :prefab_config_classpath_dir
17
- attr_reader :prefab_envs
18
- attr_reader :collect_sync_interval
19
- attr_reader :use_local_cache
20
- attr_reader :datafile
21
- attr_reader :disable_action_controller_logging
22
- attr_accessor :is_fork
23
-
24
- DEFAULT_LOG_FORMATTER = proc { |data|
25
- severity = data[:severity]
26
- datetime = data[:datetime]
27
- progname = data[:progname]
28
- path = data[:path]
29
- msg = data[:message]
30
- log_context = data[:log_context]
31
-
32
- progname = (progname.nil? || progname.empty?) ? path : "#{progname}: #{path}"
33
-
34
- formatted_log_context = log_context.sort.map do |k, v|
35
- "#{k}=#{v}"
36
- end.join(" ")
37
- "#{severity.ljust(5)} #{datetime}:#{' ' if progname}#{progname} #{msg}#{log_context.any? ? " " + formatted_log_context : ""}\n"
38
- }
39
-
40
- JSON_LOG_FORMATTER = proc { |data|
41
- log_context = data.delete(:log_context)
42
- data.merge(log_context).compact.to_json << "\n"
43
- }
44
-
45
- COMPACT_LOG_FORMATTER = proc { |data|
46
- severity = data[:severity]
47
- msg = data[:message]
48
- log_context = data[:log_context]
49
- log_context["path"] = data[:path] || ""
50
-
51
- formatted_log_context = log_context.sort.map do |k, v|
52
- "#{k}=#{v}"
53
- end.join(" ")
54
- "#{severity.ljust(5)} #{msg&.strip} #{formatted_log_context}\n"
55
- }
56
-
57
- module ON_INITIALIZATION_FAILURE
58
- RAISE = :raise
59
- RETURN = :return
60
- end
61
-
62
- module ON_NO_DEFAULT
63
- RAISE = :raise
64
- RETURN_NIL = :return_nil
65
- end
66
-
67
- module DATASOURCES
68
- ALL = :all
69
- LOCAL_ONLY = :local_only
70
- end
71
-
72
- DEFAULT_MAX_PATHS = 1_000
73
- DEFAULT_MAX_KEYS = 100_000
74
- DEFAULT_MAX_EXAMPLE_CONTEXTS = 100_000
75
- DEFAULT_MAX_EVAL_SUMMARIES = 100_000
76
-
77
- private def init(
78
- api_key: ENV['PREFAB_API_KEY'],
79
- logdev: $stdout,
80
- namespace: '',
81
- log_formatter: DEFAULT_LOG_FORMATTER,
82
- log_prefix: nil,
83
- prefab_api_url: ENV['PREFAB_API_URL'] || 'https://api.prefab.cloud',
84
- on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
85
- initialization_timeout_sec: 10, # how long to wait before on_init_failure
86
- on_init_failure: ON_INITIALIZATION_FAILURE::RAISE,
87
- prefab_datasources: ENV['PREFAB_DATASOURCES'] == 'LOCAL_ONLY' ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
88
- prefab_config_override_dir: Dir.home,
89
- prefab_config_classpath_dir: '.', # where to load local overrides
90
- prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(','),
91
- collect_logger_counts: true,
92
- collect_max_paths: DEFAULT_MAX_PATHS,
93
- collect_sync_interval: nil,
94
- context_upload_mode: :periodic_example, # :periodic_example, :shape_only, :none
95
- context_max_size: DEFAULT_MAX_EVAL_SUMMARIES,
96
- collect_evaluation_summaries: true,
97
- collect_max_evaluation_summaries: DEFAULT_MAX_EVAL_SUMMARIES,
98
- allow_telemetry_in_local_mode: false,
99
- x_datafile: ENV['PREFAB_DATAFILE'],
100
- x_use_local_cache: false,
101
- disable_action_controller_logging: false
102
- )
103
- @api_key = api_key
104
- @logdev = logdev
105
- @namespace = namespace
106
- @log_formatter = log_formatter
107
- @log_prefix = log_prefix
108
- @prefab_api_url = remove_trailing_slash(prefab_api_url)
109
- @on_no_default = on_no_default
110
- @initialization_timeout_sec = initialization_timeout_sec
111
- @on_init_failure = on_init_failure
112
- @prefab_datasources = prefab_datasources
113
- @datafile = x_datafile
114
- @prefab_config_classpath_dir = prefab_config_classpath_dir
115
- @prefab_config_override_dir = prefab_config_override_dir
116
- @prefab_envs = Array(prefab_envs)
117
- @collect_logger_counts = collect_logger_counts
118
- @collect_max_paths = collect_max_paths
119
- @collect_sync_interval = collect_sync_interval
120
- @collect_evaluation_summaries = collect_evaluation_summaries
121
- @collect_max_evaluation_summaries = collect_max_evaluation_summaries
122
- @allow_telemetry_in_local_mode = allow_telemetry_in_local_mode
123
- @use_local_cache = x_use_local_cache
124
- @disable_action_controller_logging = disable_action_controller_logging
125
- @is_fork = false
126
-
127
- # defaults that may be overridden by context_upload_mode
128
- @collect_shapes = false
129
- @collect_max_shapes = 0
130
- @collect_example_contexts = false
131
- @collect_max_example_contexts = 0
132
-
133
- case context_upload_mode
134
- when :none
135
- # do nothing
136
- when :periodic_example
137
- @collect_example_contexts = true
138
- @collect_max_example_contexts = context_max_size
139
- when :shape_only
140
- @collect_shapes = true
141
- @collect_max_shapes = context_max_size
142
- else
143
- raise "Unknown context_upload_mode #{context_upload_mode}. Please provide :periodic_example, :shape_only, or :none."
144
- end
145
- end
146
-
147
- def initialize(options = {})
148
- init(**options)
149
- end
150
-
151
- def local_only?
152
- @prefab_datasources == DATASOURCES::LOCAL_ONLY
153
- end
154
-
155
- def datafile?
156
- !@datafile.nil?
157
- end
158
-
159
- def collect_max_paths
160
- return 0 unless telemetry_allowed?(@collect_logger_counts)
161
-
162
- @collect_max_paths
163
- end
164
-
165
- def collect_max_shapes
166
- return 0 unless telemetry_allowed?(@collect_shapes)
167
-
168
- @collect_max_shapes
169
- end
170
-
171
- def collect_max_example_contexts
172
- return 0 unless telemetry_allowed?(@collect_example_contexts)
173
-
174
- @collect_max_example_contexts
175
- end
176
-
177
- def collect_max_evaluation_summaries
178
- return 0 unless telemetry_allowed?(@collect_evaluation_summaries)
179
-
180
- @collect_max_evaluation_summaries
181
- end
182
-
183
- # https://api.prefab.cloud -> https://api-prefab-cloud.global.ssl.fastly.net
184
- def url_for_api_cdn
185
- ENV['PREFAB_CDN_URL'] || "#{@prefab_api_url.gsub(/\./, '-')}.global.ssl.fastly.net"
186
- end
187
-
188
- def api_key_id
189
- @api_key&.split("-")&.first
190
- end
191
-
192
- def for_fork
193
- clone = self.clone
194
- clone.is_fork = true
195
- clone
196
- end
197
-
198
- private
199
-
200
- def telemetry_allowed?(option)
201
- option && (!local_only? || @allow_telemetry_in_local_mode)
202
- end
203
-
204
- def remove_trailing_slash(url)
205
- url.end_with?('/') ? url[0..-2] : url
206
- end
207
- end
208
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- module PeriodicSync
5
- LOG = Prefab::InternalLogger.new("periodsync")
6
- def sync
7
- return if @data.size.zero?
8
-
9
- LOG.debug "Syncing #{@data.size} items"
10
-
11
- start_at_was = @start_at
12
- @start_at = Prefab::TimeHelpers.now_in_ms
13
-
14
- flush(prepare_data, start_at_was)
15
- end
16
-
17
- def prepare_data
18
- to_ship = @data.dup
19
- @data.clear
20
-
21
- on_prepare_data
22
-
23
- to_ship
24
- end
25
-
26
- def on_prepare_data
27
- # noop -- override as you wish
28
- end
29
-
30
- def post(url, data)
31
- @client.post(url, data)
32
- end
33
-
34
- def start_periodic_sync(sync_interval)
35
- @start_at = Prefab::TimeHelpers.now_in_ms
36
-
37
- @sync_interval = calculate_sync_interval(sync_interval)
38
-
39
- Thread.new do
40
- LOG.debug "Initialized #{@name} instance_hash=#{@client.instance_hash}"
41
-
42
- loop do
43
- sleep @sync_interval.call
44
- sync
45
- end
46
- end
47
- end
48
-
49
- def pool
50
- @pool ||= Concurrent::ThreadPoolExecutor.new(
51
- fallback_policy: :discard,
52
- max_queue: 5,
53
- max_threads: 4,
54
- min_threads: 1,
55
- name: @name
56
- )
57
- end
58
-
59
- private
60
-
61
- def calculate_sync_interval(sync_interval)
62
- if sync_interval.is_a?(Numeric)
63
- proc { sync_interval }
64
- else
65
- sync_interval || ExponentialBackoff.new(initial_delay: 8, max_delay: 60 * 5)
66
- end
67
- end
68
- end
69
- end
data/lib/prefab/prefab.rb DELETED
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- @@lock = Concurrent::ReadWriteLock.new
5
-
6
- def self.init(options = Prefab::Options.new)
7
- unless @singleton.nil?
8
- Prefab::LoggerClient.instance.warn 'Prefab already initialized.'
9
- return @singleton
10
- end
11
-
12
- @@lock.with_write_lock {
13
- @singleton = Prefab::Client.new(options)
14
- }
15
- end
16
-
17
- def self.fork
18
- ensure_initialized
19
- @@lock.with_write_lock {
20
- @singleton = @singleton.fork
21
- }
22
- end
23
-
24
- def self.set_rails_loggers
25
- ensure_initialized
26
- @singleton.set_rails_loggers
27
- end
28
-
29
- def self.get(key, properties = NO_DEFAULT_PROVIDED)
30
- ensure_initialized key
31
- @singleton.get(key, properties)
32
- end
33
-
34
- def self.enabled?(feature_name, jit_context = NO_DEFAULT_PROVIDED)
35
- ensure_initialized feature_name
36
- @singleton.enabled?(feature_name, jit_context)
37
- end
38
-
39
- def self.with_context(properties, &block)
40
- ensure_initialized
41
- @singleton.with_context(properties, &block)
42
- end
43
-
44
- def self.instance
45
- ensure_initialized
46
- @singleton
47
- end
48
-
49
- private
50
-
51
- def self.ensure_initialized(key = nil)
52
- if not defined? @singleton or @singleton.nil?
53
- raise Prefab::Errors::UninitializedError.new(key)
54
- end
55
- end
56
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- # A key-based rate limiter that considers a key to be fresh if it has been
5
- # seen within the last `duration` seconds.
6
- #
7
- # This is used to rate limit the number of times we send a given context
8
- # to the server.
9
- #
10
- # Because expected usage is to immediately `set` on a `fresh?` miss, we do
11
- # not prune the data structure on `fresh?` calls. Instead, we manually invoke
12
- # `prune` periodically from the cache consumer.
13
- class RateLimitCache
14
- attr_reader :data
15
-
16
- def initialize(duration)
17
- @data = Concurrent::Map.new
18
- @duration = duration
19
- end
20
-
21
- def fresh?(key)
22
- timestamp = @data[key]
23
-
24
- return false unless timestamp
25
- return false if Time.now.utc.to_i - timestamp > @duration
26
-
27
- true
28
- end
29
-
30
- def set(key)
31
- @data[key] = Time.now.utc.to_i
32
- end
33
-
34
- def prune
35
- now = Time.now.utc.to_i
36
- @data.each_pair do |key, (timestamp, _)|
37
- @data.delete(key) if now - timestamp > @duration
38
- end
39
- end
40
- end
41
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class ResolvedConfigPresenter
5
- class ConfigRow
6
- include Comparable
7
-
8
- attr_reader :key, :value, :match, :source
9
-
10
- def initialize(key, value, match, source)
11
- @key = key
12
- @value = value
13
- @match = match
14
- @source = source
15
- end
16
-
17
- def <=>(other)
18
- inspect <=> other.inspect
19
- end
20
-
21
- def inspect
22
- [@key, @value, @match, @source].inspect
23
- end
24
- end
25
-
26
- def initialize(resolver, lock, local_store)
27
- @resolver = resolver
28
- @lock = lock
29
- @local_store = local_store
30
- end
31
-
32
- def each(&block)
33
- to_h.each(&block)
34
- end
35
-
36
- def to_h
37
- hash = {}
38
-
39
- Prefab::Context.with_context({}) do
40
- @lock.with_read_lock do
41
- @local_store.keys.sort.each do |k|
42
- v = @local_store[k]
43
-
44
- if v.nil?
45
- hash[k] = ConfigRow.new(k, nil, nil, nil)
46
- else
47
- value = @resolver.evaluate(v[:config])&.reportable_value
48
- hash[k] = ConfigRow.new(k, value, v[:match], v[:source])
49
- end
50
- end
51
- end
52
- end
53
-
54
- hash
55
- end
56
-
57
- def to_s
58
- str = "\n"
59
-
60
- Prefab::Context.with_context({}) do
61
- @lock.with_read_lock do
62
- @local_store.keys.sort.each do |k|
63
- v = @local_store[k]
64
- elements = [k.slice(0..49).ljust(50)]
65
- if v.nil?
66
- elements << 'tombstone'
67
- else
68
- value = begin
69
- @resolver.evaluate(v[:config])&.reportable_value
70
- rescue StandardError => e
71
- "ERROR EVALUATING: #{e.class} #{e.message}"
72
- end
73
- elements << value.to_s.slice(0..34).ljust(35)
74
- elements << value.class.to_s.slice(0..6).ljust(7)
75
- elements << "Match: #{v[:match]}".slice(0..29).ljust(30)
76
- elements << "Source: #{v[:source]}"
77
- end
78
- str += elements.join(' | ') << "\n"
79
- end
80
- end
81
- end
82
-
83
- str
84
- end
85
- end
86
- end
@@ -1,7 +0,0 @@
1
- module Prefab
2
- module TimeHelpers
3
- def self.now_in_ms
4
- ::Time.now.utc.to_i * 1000
5
- end
6
- end
7
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class WeightedValueResolver
5
- MAX_32_FLOAT = 4_294_967_294.0
6
-
7
- def initialize(weights, config_key, context_hash_value)
8
- @weights = weights
9
- @config_key = config_key
10
- @context_hash_value = context_hash_value
11
- end
12
-
13
- def resolve
14
- percent = @context_hash_value ? user_percent : rand
15
-
16
- index = variant_index(percent)
17
-
18
- [@weights[index], index]
19
- end
20
-
21
- def user_percent
22
- to_hash = "#{@config_key}#{@context_hash_value}"
23
- int_value = Murmur3.murmur3_32(to_hash)
24
- int_value / MAX_32_FLOAT
25
- end
26
-
27
- def variant_index(percent_through_distribution)
28
- distribution_space = @weights.inject(0) { |sum, v| sum + v.weight }
29
- bucket = distribution_space * percent_through_distribution
30
-
31
- sum = 0
32
- @weights.each_with_index do |variant_weight, index|
33
- return index if bucket < sum + variant_weight.weight
34
-
35
- sum += variant_weight.weight
36
- end
37
-
38
- # In the event that all weights are zero, return the last variant
39
- @weights.size - 1
40
- end
41
- end
42
- end
@@ -1,34 +0,0 @@
1
- require 'yaml'
2
-
3
- module Prefab
4
- class YAMLConfigParser
5
- LOG = Prefab::InternalLogger.new(YAMLConfigParser)
6
-
7
- def initialize(file, client)
8
- @file = file
9
- @client = client
10
- end
11
-
12
- def merge(config)
13
- yaml = load
14
-
15
- yaml.each do |k, v|
16
- config = Prefab::LocalConfigParser.parse(k, v, config, @file)
17
- end
18
-
19
- config
20
- end
21
-
22
- private
23
-
24
- def load
25
- if File.exist?(@file)
26
- LOG.info "Load #{@file}"
27
- YAML.load_file(@file)
28
- else
29
- LOG.info "No file #{@file}"
30
- {}
31
- end
32
- end
33
- end
34
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- NO_DEFAULT_PROVIDED = :no_default_provided
5
- VERSION = File.read(File.dirname(__FILE__) + '/../VERSION').strip
6
- end
7
-
8
- require 'concurrent/atomics'
9
- require 'concurrent'
10
- require 'faraday'
11
- require 'openssl'
12
- require 'ld-eventsource'
13
- require 'prefab_pb'
14
- require 'prefab/time_helpers'
15
- require 'prefab/error'
16
- require 'prefab/evaluation'
17
- require 'prefab/encryption'
18
- require 'prefab/exponential_backoff'
19
- require 'prefab/errors/initialization_timeout_error'
20
- require 'prefab/errors/invalid_api_key_error'
21
- require 'prefab/errors/missing_default_error'
22
- require 'prefab/errors/env_var_parse_error'
23
- require 'prefab/errors/missing_env_var_error'
24
- require 'prefab/errors/uninitialized_error'
25
- require 'prefab/options'
26
- require 'prefab/static_logger'
27
- require 'prefab/internal_logger'
28
- require 'prefab/rate_limit_cache'
29
- require 'prefab/context_shape_aggregator'
30
- require 'prefab/example_contexts_aggregator'
31
- require 'prefab/evaluation_summary_aggregator'
32
- require 'prefab/log_path_aggregator'
33
- require 'prefab/sse_logger'
34
- require 'prefab/weighted_value_resolver'
35
- require 'prefab/config_value_wrapper'
36
- require 'prefab/config_value_unwrapper'
37
- require 'prefab/criteria_evaluator'
38
- require 'prefab/config_loader'
39
- require 'prefab/context_shape'
40
- require 'prefab/local_config_parser'
41
- require 'prefab/yaml_config_parser'
42
- require 'prefab/resolved_config_presenter'
43
- require 'prefab/config_resolver'
44
- require 'prefab/http_connection'
45
- require 'prefab/context'
46
- require 'prefab/logger_client'
47
- require 'active_support/deprecation'
48
- require 'active_support'
49
- require 'action_controller/metal/strong_parameters'
50
- require 'prefab/logging/formatter_base'
51
- require 'prefab/log_subscribers/action_controller_subscriber'
52
- require 'prefab/client'
53
- require 'prefab/config_client_presenter'
54
- require 'prefab/config_client'
55
- require 'prefab/feature_flag_client'
56
- require 'prefab/prefab'
57
- require 'prefab/murmer3'