prefab-cloud-ruby 0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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'