prefab-cloud-ruby 0.24.5 → 1.0.0

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/VERSION +1 -1
  4. data/compile_protos.sh +7 -0
  5. data/lib/prefab/client.rb +20 -46
  6. data/lib/prefab/config_client.rb +9 -12
  7. data/lib/prefab/config_resolver.rb +2 -1
  8. data/lib/prefab/config_value_unwrapper.rb +20 -9
  9. data/lib/prefab/context.rb +43 -7
  10. data/lib/prefab/context_shape_aggregator.rb +1 -1
  11. data/lib/prefab/criteria_evaluator.rb +24 -16
  12. data/lib/prefab/evaluation.rb +48 -0
  13. data/lib/prefab/evaluation_summary_aggregator.rb +85 -0
  14. data/lib/prefab/example_contexts_aggregator.rb +76 -0
  15. data/lib/prefab/exponential_backoff.rb +5 -0
  16. data/lib/prefab/feature_flag_client.rb +0 -2
  17. data/lib/prefab/log_path_aggregator.rb +1 -1
  18. data/lib/prefab/logger_client.rb +12 -13
  19. data/lib/prefab/options.rb +52 -43
  20. data/lib/prefab/periodic_sync.rb +30 -13
  21. data/lib/prefab/rate_limit_cache.rb +41 -0
  22. data/lib/prefab/resolved_config_presenter.rb +2 -4
  23. data/lib/prefab/weighted_value_resolver.rb +1 -1
  24. data/lib/prefab-cloud-ruby.rb +5 -5
  25. data/lib/prefab_pb.rb +11 -1
  26. data/prefab-cloud-ruby.gemspec +14 -9
  27. data/test/integration_test.rb +1 -3
  28. data/test/integration_test_helpers.rb +0 -1
  29. data/test/support/common_helpers.rb +174 -0
  30. data/test/support/mock_base_client.rb +44 -0
  31. data/test/support/mock_config_client.rb +19 -0
  32. data/test/support/mock_config_loader.rb +1 -0
  33. data/test/test_client.rb +354 -40
  34. data/test/test_config_client.rb +1 -0
  35. data/test/test_config_loader.rb +1 -0
  36. data/test/test_config_resolver.rb +25 -24
  37. data/test/test_config_value_unwrapper.rb +22 -32
  38. data/test/test_context.rb +1 -0
  39. data/test/test_context_shape_aggregator.rb +11 -1
  40. data/test/test_criteria_evaluator.rb +180 -133
  41. data/test/test_evaluation_summary_aggregator.rb +162 -0
  42. data/test/test_example_contexts_aggregator.rb +238 -0
  43. data/test/test_helper.rb +5 -131
  44. data/test/test_integration.rb +6 -4
  45. data/test/test_local_config_parser.rb +2 -2
  46. data/test/test_log_path_aggregator.rb +9 -1
  47. data/test/test_logger.rb +6 -5
  48. data/test/test_options.rb +33 -2
  49. data/test/test_rate_limit_cache.rb +44 -0
  50. data/test/test_weighted_value_resolver.rb +13 -7
  51. metadata +13 -8
  52. data/lib/prefab/evaluated_configs_aggregator.rb +0 -60
  53. data/lib/prefab/evaluated_keys_aggregator.rb +0 -41
  54. data/lib/prefab/noop_cache.rb +0 -15
  55. data/lib/prefab/noop_stats.rb +0 -8
  56. data/test/test_evaluated_configs_aggregator.rb +0 -254
  57. data/test/test_evaluated_keys_aggregator.rb +0 -54
@@ -15,7 +15,7 @@ module Prefab
15
15
  PrefabProto::LogLevel::WARN => ::Logger::WARN,
16
16
  PrefabProto::LogLevel::ERROR => ::Logger::ERROR,
17
17
  PrefabProto::LogLevel::FATAL => ::Logger::FATAL
18
- }
18
+ }.freeze
19
19
 
20
20
  def initialize(logdev, log_path_aggregator: nil, formatter: nil, prefix: nil)
21
21
  super(logdev)
@@ -27,7 +27,7 @@ module Prefab
27
27
  @log_path_aggregator = log_path_aggregator
28
28
  end
29
29
 
30
- def add(severity, message = nil, progname = nil, loc, &block)
30
+ def add_internal(severity, message, progname, loc, &block)
31
31
  path_loc = get_loc_path(loc)
32
32
  path = @prefix + path_loc
33
33
 
@@ -36,7 +36,7 @@ module Prefab
36
36
  log(message, path, progname, severity, &block)
37
37
  end
38
38
 
39
- def log_internal(message, path = nil, progname, severity, &block)
39
+ def log_internal(message, path, progname, severity, &block)
40
40
  path = if path
41
41
  "#{INTERNAL_PREFIX}.#{path}"
42
42
  else
@@ -51,9 +51,8 @@ module Prefab
51
51
 
52
52
  return true if @logdev.nil? || severity < level_of(path) || @silences[local_log_id]
53
53
 
54
- if progname.nil?
55
- progname = @progname
56
- end
54
+ progname = @progname if progname.nil?
55
+
57
56
  if message.nil?
58
57
  if block_given?
59
58
  message = yield
@@ -70,23 +69,23 @@ module Prefab
70
69
  end
71
70
 
72
71
  def debug(progname = nil, &block)
73
- add(DEBUG, nil, progname, caller_locations(1, 1)[0], &block)
72
+ add_internal(DEBUG, nil, progname, caller_locations(1, 1)[0], &block)
74
73
  end
75
74
 
76
75
  def info(progname = nil, &block)
77
- add(INFO, nil, progname, caller_locations(1, 1)[0], &block)
76
+ add_internal(INFO, nil, progname, caller_locations(1, 1)[0], &block)
78
77
  end
79
78
 
80
79
  def warn(progname = nil, &block)
81
- add(WARN, nil, progname, caller_locations(1, 1)[0], &block)
80
+ add_internal(WARN, nil, progname, caller_locations(1, 1)[0], &block)
82
81
  end
83
82
 
84
83
  def error(progname = nil, &block)
85
- add(ERROR, nil, progname, caller_locations(1, 1)[0], &block)
84
+ add_internal(ERROR, nil, progname, caller_locations(1, 1)[0], &block)
86
85
  end
87
86
 
88
87
  def fatal(progname = nil, &block)
89
- add(FATAL, nil, progname, caller_locations(1, 1)[0], &block)
88
+ add_internal(FATAL, nil, progname, caller_locations(1, 1)[0], &block)
90
89
  end
91
90
 
92
91
  def debug?
@@ -113,7 +112,7 @@ module Prefab
113
112
  DEBUG
114
113
  end
115
114
 
116
- def set_config_client(config_client)
115
+ def config_client=(config_client)
117
116
  @config_client = config_client
118
117
  end
119
118
 
@@ -169,7 +168,7 @@ module Prefab
169
168
  path
170
169
  end
171
170
 
172
- def format_message(severity, datetime, progname, msg, path)
171
+ def format_message(severity, datetime, progname, msg, path = nil)
173
172
  formatter = (@formatter || @default_formatter)
174
173
 
175
174
  if formatter.arity == 5
@@ -1,13 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prefab
4
+ # This class contains all the options that can be passed to the Prefab client.
4
5
  class Options
5
6
  attr_reader :api_key
6
7
  attr_reader :logdev
7
8
  attr_reader :log_prefix
8
9
  attr_reader :log_formatter
9
- attr_reader :stats
10
- attr_reader :shared_cache
11
10
  attr_reader :namespace
12
11
  attr_reader :prefab_api_url
13
12
  attr_reader :on_no_default
@@ -17,7 +16,6 @@ module Prefab
17
16
  attr_reader :prefab_config_classpath_dir
18
17
  attr_reader :prefab_envs
19
18
  attr_reader :collect_sync_interval
20
- attr_reader :shape_sync_interval
21
19
 
22
20
  DEFAULT_LOG_FORMATTER = proc { |severity, datetime, progname, msg|
23
21
  "#{severity.ljust(5)} #{datetime}:#{' ' if progname}#{progname} #{msg}\n"
@@ -33,58 +31,50 @@ module Prefab
33
31
  }
34
32
 
35
33
  module ON_INITIALIZATION_FAILURE
36
- RAISE = 1
37
- RETURN = 2
34
+ RAISE = :raise
35
+ RETURN = :return
38
36
  end
39
37
 
40
38
  module ON_NO_DEFAULT
41
- RAISE = 1
42
- RETURN_NIL = 2
39
+ RAISE = :raise
40
+ RETURN_NIL = :return_nil
43
41
  end
44
42
 
45
43
  module DATASOURCES
46
- ALL = 1
47
- LOCAL_ONLY = 2
44
+ ALL = :all
45
+ LOCAL_ONLY = :local_only
48
46
  end
49
47
 
50
48
  DEFAULT_MAX_PATHS = 1_000
51
- DEFAULT_MAX_CONTEXT_KEYS = 100_000
52
49
  DEFAULT_MAX_KEYS = 100_000
53
- DEFAULT_MAX_EVALS = 100_000
50
+ DEFAULT_MAX_EXAMPLE_CONTEXTS = 100_000
51
+ DEFAULT_MAX_EVAL_SUMMARIES = 100_000
54
52
 
55
53
  private def init(
56
54
  api_key: ENV['PREFAB_API_KEY'],
57
55
  logdev: $stdout,
58
- stats: NoopStats.new, # receives increment("prefab.limitcheck", {:tags=>["policy_group:page_view", "pass:true"]})
59
- shared_cache: NoopCache.new, # Something that quacks like Rails.cache ideally memcached
60
56
  namespace: '',
61
57
  log_formatter: DEFAULT_LOG_FORMATTER,
62
58
  log_prefix: nil,
63
59
  prefab_api_url: ENV['PREFAB_API_URL'] || 'https://api.prefab.cloud',
64
60
  on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
65
61
  initialization_timeout_sec: 10, # how long to wait before on_init_failure
66
- on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, # options :unlock_and_continue, :lock_and_keep_trying, :raise
67
- # new_config_callback: nil, #callback method
68
- # live_override_url: nil,
62
+ on_init_failure: ON_INITIALIZATION_FAILURE::RAISE,
69
63
  prefab_datasources: ENV['PREFAB_DATASOURCES'] == 'LOCAL_ONLY' ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
70
64
  prefab_config_override_dir: Dir.home,
71
- prefab_config_classpath_dir: '.',
65
+ prefab_config_classpath_dir: '.', # where to load local overrides
72
66
  prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(','),
73
- collect_logs: true,
67
+ collect_logger_counts: true,
74
68
  collect_max_paths: DEFAULT_MAX_PATHS,
75
69
  collect_sync_interval: nil,
76
- collect_shapes: true,
77
- collect_max_shapes: DEFAULT_MAX_CONTEXT_KEYS,
78
- collect_keys: false,
79
- collect_max_keys: DEFAULT_MAX_KEYS,
80
- collect_evaluations: false,
81
- collect_max_evaluations: DEFAULT_MAX_EVALS,
82
- shape_sync_interval: nil
70
+ context_upload_mode: :periodic_example, # :periodic_example, :shape_only, :none
71
+ context_max_size: DEFAULT_MAX_EVAL_SUMMARIES,
72
+ collect_evaluation_summaries: true,
73
+ collect_max_evaluation_summaries: DEFAULT_MAX_EVAL_SUMMARIES,
74
+ allow_telemetry_in_local_mode: false
83
75
  )
84
76
  @api_key = api_key
85
77
  @logdev = logdev
86
- @stats = stats
87
- @shared_cache = shared_cache
88
78
  @namespace = namespace
89
79
  @log_formatter = log_formatter
90
80
  @log_prefix = log_prefix
@@ -96,16 +86,31 @@ module Prefab
96
86
  @prefab_config_classpath_dir = prefab_config_classpath_dir
97
87
  @prefab_config_override_dir = prefab_config_override_dir
98
88
  @prefab_envs = Array(prefab_envs)
99
- @collect_logs = collect_logs
89
+ @collect_logger_counts = collect_logger_counts
100
90
  @collect_max_paths = collect_max_paths
101
91
  @collect_sync_interval = collect_sync_interval
102
- @collect_shapes = collect_shapes
103
- @collect_max_shapes = collect_max_shapes
104
- @collect_keys = collect_keys
105
- @collect_max_keys = collect_max_keys
106
- @shape_sync_interval = shape_sync_interval
107
- @collect_evaluations = collect_evaluations
108
- @collect_max_evaluations = collect_max_evaluations
92
+ @collect_evaluation_summaries = collect_evaluation_summaries
93
+ @collect_max_evaluation_summaries = collect_max_evaluation_summaries
94
+ @allow_telemetry_in_local_mode = allow_telemetry_in_local_mode
95
+
96
+ # defaults that may be overridden by context_upload_mode
97
+ @collect_shapes = false
98
+ @collect_max_shapes = 0
99
+ @collect_example_contexts = false
100
+ @collect_max_example_contexts = 0
101
+
102
+ case context_upload_mode
103
+ when :none
104
+ # do nothing
105
+ when :periodic_example
106
+ @collect_example_contexts = true
107
+ @collect_max_example_contexts = context_max_size
108
+ when :shape_only
109
+ @collect_shapes = true
110
+ @collect_max_shapes = context_max_size
111
+ else
112
+ raise "Unknown context_upload_mode #{context_upload_mode}. Please provide :periodic_example, :shape_only, or :none."
113
+ end
109
114
  end
110
115
 
111
116
  def initialize(options = {})
@@ -117,27 +122,27 @@ module Prefab
117
122
  end
118
123
 
119
124
  def collect_max_paths
120
- return 0 if !@collect_logs || local_only?
125
+ return 0 unless telemetry_allowed?(@collect_logger_counts)
121
126
 
122
127
  @collect_max_paths
123
128
  end
124
129
 
125
130
  def collect_max_shapes
126
- return 0 if !@collect_shapes || local_only?
131
+ return 0 unless telemetry_allowed?(@collect_shapes)
127
132
 
128
133
  @collect_max_shapes
129
134
  end
130
135
 
131
- def collect_max_keys
132
- return 0 if !@collect_keys || local_only?
136
+ def collect_max_example_contexts
137
+ return 0 unless telemetry_allowed?(@collect_example_contexts)
133
138
 
134
- @collect_max_keys
139
+ @collect_max_example_contexts
135
140
  end
136
141
 
137
- def collect_max_evaluations
138
- return 0 if !@collect_evaluations || local_only?
142
+ def collect_max_evaluation_summaries
143
+ return 0 unless telemetry_allowed?(@collect_evaluation_summaries)
139
144
 
140
- @collect_max_evaluations
145
+ @collect_max_evaluation_summaries
141
146
  end
142
147
 
143
148
  # https://api.prefab.cloud -> https://api-prefab-cloud.global.ssl.fastly.net
@@ -147,6 +152,10 @@ module Prefab
147
152
 
148
153
  private
149
154
 
155
+ def telemetry_allowed?(option)
156
+ option && (!local_only? || @allow_telemetry_in_local_mode)
157
+ end
158
+
150
159
  def remove_trailing_slash(url)
151
160
  url.end_with?('/') ? url[0..-2] : url
152
161
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Prefab
2
4
  module PeriodicSync
3
5
  def sync
@@ -14,25 +16,20 @@ module Prefab
14
16
  def prepare_data
15
17
  to_ship = @data.dup
16
18
  @data.clear
19
+
20
+ on_prepare_data
21
+
17
22
  to_ship
18
23
  end
19
24
 
25
+ def on_prepare_data
26
+ # noop -- override as you wish
27
+ end
28
+
20
29
  def start_periodic_sync(sync_interval)
21
30
  @start_at = Prefab::TimeHelpers.now_in_ms
22
31
 
23
- @sync_interval = if sync_interval.is_a?(Numeric)
24
- proc { sync_interval }
25
- else
26
- sync_interval || ExponentialBackoff.new(initial_delay: 8, max_delay: 60 * 10)
27
- end
28
-
29
- @pool = Concurrent::ThreadPoolExecutor.new(
30
- fallback_policy: :discard,
31
- max_queue: 5,
32
- max_threads: 4,
33
- min_threads: 1,
34
- name: @name
35
- )
32
+ @sync_interval = calculate_sync_interval(sync_interval)
36
33
 
37
34
  Thread.new do
38
35
  log_internal "Initialized #{@name} instance_hash=#{@client.instance_hash}"
@@ -47,5 +44,25 @@ module Prefab
47
44
  def log_internal(message)
48
45
  @client.log.log_internal message, @name, nil, ::Logger::DEBUG
49
46
  end
47
+
48
+ def pool
49
+ @pool ||= Concurrent::ThreadPoolExecutor.new(
50
+ fallback_policy: :discard,
51
+ max_queue: 5,
52
+ max_threads: 4,
53
+ min_threads: 1,
54
+ name: @name
55
+ )
56
+ end
57
+
58
+ private
59
+
60
+ def calculate_sync_interval(sync_interval)
61
+ if sync_interval.is_a?(Numeric)
62
+ proc { sync_interval }
63
+ else
64
+ sync_interval || ExponentialBackoff.new(initial_delay: 8, max_delay: 60 * 5)
65
+ end
66
+ end
50
67
  end
51
68
  end
@@ -0,0 +1,41 @@
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
@@ -44,8 +44,7 @@ module Prefab
44
44
  if v.nil?
45
45
  hash[k] = ConfigRow.new(k, nil, nil, nil)
46
46
  else
47
- config = @resolver.evaluate(v[:config])
48
- value = Prefab::ConfigValueUnwrapper.unwrap(config, k, Prefab::Context.new)
47
+ value = @resolver.evaluate(v[:config])&.unwrapped_value
49
48
  hash[k] = ConfigRow.new(k, value, v[:match], v[:source])
50
49
  end
51
50
  end
@@ -66,8 +65,7 @@ module Prefab
66
65
  if v.nil?
67
66
  elements << 'tombstone'
68
67
  else
69
- config = @resolver.evaluate(v[:config], {})
70
- value = Prefab::ConfigValueUnwrapper.unwrap(config, k, Prefab::Context.new)
68
+ value = @resolver.evaluate(v[:config])&.unwrapped_value
71
69
  elements << value.to_s.slice(0..34).ljust(35)
72
70
  elements << value.class.to_s.slice(0..6).ljust(7)
73
71
  elements << "Match: #{v[:match]}".slice(0..29).ljust(30)
@@ -15,7 +15,7 @@ module Prefab
15
15
 
16
16
  index = variant_index(percent)
17
17
 
18
- @weights[index]
18
+ [@weights[index], index]
19
19
  end
20
20
 
21
21
  def user_percent
@@ -13,16 +13,18 @@ require 'ld-eventsource'
13
13
  require 'prefab_pb'
14
14
  require 'prefab/time_helpers'
15
15
  require 'prefab/error'
16
+ require 'prefab/evaluation'
16
17
  require 'prefab/exponential_backoff'
17
18
  require 'prefab/errors/initialization_timeout_error'
18
19
  require 'prefab/errors/invalid_api_key_error'
19
20
  require 'prefab/errors/missing_default_error'
20
21
  require 'prefab/options'
21
22
  require 'prefab/internal_logger'
22
- require 'prefab/log_path_aggregator'
23
+ require 'prefab/rate_limit_cache'
23
24
  require 'prefab/context_shape_aggregator'
24
- require 'prefab/evaluated_configs_aggregator'
25
- require 'prefab/evaluated_keys_aggregator'
25
+ require 'prefab/example_contexts_aggregator'
26
+ require 'prefab/evaluation_summary_aggregator'
27
+ require 'prefab/log_path_aggregator'
26
28
  require 'prefab/sse_logger'
27
29
  require 'prefab/weighted_value_resolver'
28
30
  require 'prefab/config_value_wrapper'
@@ -40,6 +42,4 @@ require 'prefab/logger_client'
40
42
  require 'prefab/client'
41
43
  require 'prefab/config_client'
42
44
  require 'prefab/feature_flag_client'
43
- require 'prefab/noop_cache'
44
- require 'prefab/noop_stats'
45
45
  require 'prefab/murmer3'
data/lib/prefab_pb.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  require 'google/protobuf'
6
6
 
7
7
 
8
- descriptor_data = "\n\x0cprefab.proto\x12\x06prefab\"W\n\x14\x43onfigServicePointer\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x13\n\x0bstart_at_id\x18\x02 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x03 \x01(\x03\"\xca\x02\n\x0b\x43onfigValue\x12\r\n\x03int\x18\x01 \x01(\x03H\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x0f\n\x05\x62ytes\x18\x03 \x01(\x0cH\x00\x12\x10\n\x06\x64ouble\x18\x04 \x01(\x01H\x00\x12\x0e\n\x04\x62ool\x18\x05 \x01(\x08H\x00\x12\x31\n\x0fweighted_values\x18\x06 \x01(\x0b\x32\x16.prefab.WeightedValuesH\x00\x12\x33\n\x10limit_definition\x18\x07 \x01(\x0b\x32\x17.prefab.LimitDefinitionH\x00\x12%\n\tlog_level\x18\t \x01(\x0e\x32\x10.prefab.LogLevelH\x00\x12)\n\x0bstring_list\x18\n \x01(\x0b\x32\x12.prefab.StringListH\x00\x12%\n\tint_range\x18\x0b \x01(\x0b\x32\x10.prefab.IntRangeH\x00\x42\x06\n\x04type\"B\n\x08IntRange\x12\x12\n\x05start\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x10\n\x03\x65nd\x18\x02 \x01(\x03H\x01\x88\x01\x01\x42\x08\n\x06_startB\x06\n\x04_end\"\x1c\n\nStringList\x12\x0e\n\x06values\x18\x01 \x03(\t\"C\n\rWeightedValue\x12\x0e\n\x06weight\x18\x01 \x01(\x05\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"~\n\x0eWeightedValues\x12.\n\x0fweighted_values\x18\x01 \x03(\x0b\x32\x15.prefab.WeightedValue\x12\"\n\x15hash_by_property_name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x18\n\x16_hash_by_property_name\"h\n\x07\x43onfigs\x12\x1f\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x0e.prefab.Config\x12<\n\x16\x63onfig_service_pointer\x18\x02 \x01(\x0b\x32\x1c.prefab.ConfigServicePointer\"\xf7\x01\n\x06\x43onfig\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x12\n\nproject_id\x18\x02 \x01(\x03\x12\x0b\n\x03key\x18\x03 \x01(\t\x12%\n\nchanged_by\x18\x04 \x01(\x0b\x32\x11.prefab.ChangedBy\x12\x1f\n\x04rows\x18\x05 \x03(\x0b\x32\x11.prefab.ConfigRow\x12-\n\x10\x61llowable_values\x18\x06 \x03(\x0b\x32\x13.prefab.ConfigValue\x12\'\n\x0b\x63onfig_type\x18\x07 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x14\n\x07\x64raftId\x18\x08 \x01(\x03H\x00\x88\x01\x01\x42\n\n\x08_draftId\"+\n\tChangedBy\x12\x0f\n\x07user_id\x18\x01 \x01(\x03\x12\r\n\x05\x65mail\x18\x02 \x01(\t\"\xe4\x01\n\tConfigRow\x12\x1b\n\x0eproject_env_id\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12(\n\x06values\x18\x02 \x03(\x0b\x32\x18.prefab.ConditionalValue\x12\x35\n\nproperties\x18\x03 \x03(\x0b\x32!.prefab.ConfigRow.PropertiesEntry\x1a\x46\n\x0fPropertiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x11\n\x0f_project_env_id\"[\n\x10\x43onditionalValue\x12#\n\x08\x63riteria\x18\x01 \x03(\x0b\x32\x11.prefab.Criterion\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x94\x03\n\tCriterion\x12\x15\n\rproperty_name\x18\x01 \x01(\t\x12\x35\n\x08operator\x18\x02 \x01(\x0e\x32#.prefab.Criterion.CriterionOperator\x12+\n\x0evalue_to_match\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x8b\x02\n\x11\x43riterionOperator\x12\x0b\n\x07NOT_SET\x10\x00\x12\x11\n\rLOOKUP_KEY_IN\x10\x01\x12\x15\n\x11LOOKUP_KEY_NOT_IN\x10\x02\x12\n\n\x06IN_SEG\x10\x03\x12\x0e\n\nNOT_IN_SEG\x10\x04\x12\x0f\n\x0b\x41LWAYS_TRUE\x10\x05\x12\x12\n\x0ePROP_IS_ONE_OF\x10\x06\x12\x16\n\x12PROP_IS_NOT_ONE_OF\x10\x07\x12\x19\n\x15PROP_ENDS_WITH_ONE_OF\x10\x08\x12!\n\x1dPROP_DOES_NOT_END_WITH_ONE_OF\x10\t\x12\x16\n\x12HIERARCHICAL_MATCH\x10\n\x12\x10\n\x0cIN_INT_RANGE\x10\x0b\"\x89\x01\n\x07Loggers\x12\x1f\n\x07loggers\x18\x01 \x03(\x0b\x32\x0e.prefab.Logger\x12\x10\n\x08start_at\x18\x02 \x01(\x03\x12\x0e\n\x06\x65nd_at\x18\x03 \x01(\x03\x12\x15\n\rinstance_hash\x18\x04 \x01(\t\x12\x16\n\tnamespace\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\xd9\x01\n\x06Logger\x12\x13\n\x0blogger_name\x18\x01 \x01(\t\x12\x13\n\x06traces\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x13\n\x06\x64\x65\x62ugs\x18\x03 \x01(\x03H\x01\x88\x01\x01\x12\x12\n\x05infos\x18\x04 \x01(\x03H\x02\x88\x01\x01\x12\x12\n\x05warns\x18\x05 \x01(\x03H\x03\x88\x01\x01\x12\x13\n\x06\x65rrors\x18\x06 \x01(\x03H\x04\x88\x01\x01\x12\x13\n\x06\x66\x61tals\x18\x07 \x01(\x03H\x05\x88\x01\x01\x42\t\n\x07_tracesB\t\n\x07_debugsB\x08\n\x06_infosB\x08\n\x06_warnsB\t\n\x07_errorsB\t\n\x07_fatals\"\x16\n\x14LoggerReportResponse\"\xdb\x03\n\rLimitResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\nexpires_at\x18\x02 \x01(\x03\x12\x16\n\x0e\x65nforced_group\x18\x03 \x01(\t\x12\x16\n\x0e\x63urrent_bucket\x18\x04 \x01(\x03\x12\x14\n\x0cpolicy_group\x18\x05 \x01(\t\x12;\n\x0bpolicy_name\x18\x06 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\x14\n\x0cpolicy_limit\x18\x07 \x01(\x05\x12\x0e\n\x06\x61mount\x18\x08 \x01(\x03\x12\x16\n\x0elimit_reset_at\x18\t \x01(\x03\x12\x39\n\x0csafety_level\x18\n \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"\xa9\x01\n\x10LimitPolicyNames\x12\x0b\n\x07NOT_SET\x10\x00\x12\x14\n\x10SECONDLY_ROLLING\x10\x01\x12\x14\n\x10MINUTELY_ROLLING\x10\x03\x12\x12\n\x0eHOURLY_ROLLING\x10\x05\x12\x11\n\rDAILY_ROLLING\x10\x07\x12\x13\n\x0fMONTHLY_ROLLING\x10\x08\x12\x0c\n\x08INFINITE\x10\t\x12\x12\n\x0eYEARLY_ROLLING\x10\n\"\x99\x02\n\x0cLimitRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x16\n\x0e\x61\x63quire_amount\x18\x02 \x01(\x05\x12\x0e\n\x06groups\x18\x03 \x03(\t\x12:\n\x0elimit_combiner\x18\x04 \x01(\x0e\x32\".prefab.LimitRequest.LimitCombiner\x12\x1e\n\x16\x61llow_partial_response\x18\x05 \x01(\x08\x12\x39\n\x0csafety_level\x18\x06 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"6\n\rLimitCombiner\x12\x0b\n\x07NOT_SET\x10\x00\x12\x0b\n\x07MINIMUM\x10\x01\x12\x0b\n\x07MAXIMUM\x10\x02\"/\n\nContextSet\x12!\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x0f.prefab.Context\"\x96\x01\n\x07\x43ontext\x12\x11\n\x04type\x18\x01 \x01(\tH\x00\x88\x01\x01\x12+\n\x06values\x18\x02 \x03(\x0b\x32\x1b.prefab.Context.ValuesEntry\x1a\x42\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x07\n\x05_type\"\x93\x01\n\x08Identity\x12\x13\n\x06lookup\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x34\n\nattributes\x18\x02 \x03(\x0b\x32 .prefab.Identity.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_lookup\"\x89\x01\n\x11\x43lientConfigValue\x12\x10\n\x03int\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x13\n\x06string\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x64ouble\x18\x03 \x01(\x01H\x02\x88\x01\x01\x12\x11\n\x04\x62ool\x18\x04 \x01(\x08H\x03\x88\x01\x01\x42\x06\n\x04_intB\t\n\x07_stringB\t\n\x07_doubleB\x07\n\x05_bool\"\x94\x01\n\x11\x43onfigEvaluations\x12\x35\n\x06values\x18\x01 \x03(\x0b\x32%.prefab.ConfigEvaluations.ValuesEntry\x1aH\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.prefab.ClientConfigValue:\x02\x38\x01\"\xa8\x02\n\x0fLimitDefinition\x12;\n\x0bpolicy_name\x18\x02 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\r\n\x05limit\x18\x03 \x01(\x05\x12\r\n\x05\x62urst\x18\x04 \x01(\x05\x12\x12\n\naccount_id\x18\x05 \x01(\x03\x12\x15\n\rlast_modified\x18\x06 \x01(\x03\x12\x12\n\nreturnable\x18\x07 \x01(\x08\x12\x39\n\x0csafety_level\x18\x08 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"@\n\x0bSafetyLevel\x12\x0b\n\x07NOT_SET\x10\x00\x12\x12\n\x0eL4_BEST_EFFORT\x10\x04\x12\x10\n\x0cL5_BOMBPROOF\x10\x05\"@\n\x10LimitDefinitions\x12,\n\x0b\x64\x65\x66initions\x18\x01 \x03(\x0b\x32\x17.prefab.LimitDefinition\"\x8a\x01\n\x0f\x42ufferedRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x14\n\x0c\x63ontent_type\x18\x06 \x01(\t\x12\x0c\n\x04\x66ifo\x18\x07 \x01(\x08\"\x94\x01\n\x0c\x42\x61tchRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x16\n\x0e\x62\x61tch_template\x18\x06 \x01(\t\x12\x17\n\x0f\x62\x61tch_separator\x18\x07 \x01(\t\" \n\rBasicResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\"3\n\x10\x43reationResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0e\n\x06new_id\x18\x02 \x01(\x03\"h\n\x07IdBlock\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\r\n\x05start\x18\x04 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x03\"a\n\x0eIdBlockRequest\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x03\"\x8a\x01\n\x0c\x43ontextShape\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x39\n\x0b\x66ield_types\x18\x02 \x03(\x0b\x32$.prefab.ContextShape.FieldTypesEntry\x1a\x31\n\x0f\x46ieldTypesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"[\n\rContextShapes\x12$\n\x06shapes\x18\x01 \x03(\x0b\x32\x14.prefab.ContextShape\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"C\n\rEvaluatedKeys\x12\x0c\n\x04keys\x18\x01 \x03(\t\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\x93\x01\n\x0f\x45valuatedConfig\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x16\n\x0e\x63onfig_version\x18\x02 \x01(\x03\x12#\n\x06result\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\x12#\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x12.prefab.ContextSet\x12\x11\n\ttimestamp\x18\x05 \x01(\x03\"<\n\x10\x45valuatedConfigs\x12(\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x17.prefab.EvaluatedConfig*u\n\nConfigType\x12\x17\n\x13NOT_SET_CONFIG_TYPE\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\x10\n\x0c\x46\x45\x41TURE_FLAG\x10\x02\x12\r\n\tLOG_LEVEL\x10\x03\x12\x0b\n\x07SEGMENT\x10\x04\x12\x14\n\x10LIMIT_DEFINITION\x10\x05*a\n\x08LogLevel\x12\x15\n\x11NOT_SET_LOG_LEVEL\x10\x00\x12\t\n\x05TRACE\x10\x01\x12\t\n\x05\x44\x45\x42UG\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\x08\n\x04WARN\x10\x05\x12\t\n\x05\x45RROR\x10\x06\x12\t\n\x05\x46\x41TAL\x10\t*G\n\tOnFailure\x12\x0b\n\x07NOT_SET\x10\x00\x12\x10\n\x0cLOG_AND_PASS\x10\x01\x12\x10\n\x0cLOG_AND_FAIL\x10\x02\x12\t\n\x05THROW\x10\x03\x42\x1d\n\x13\x63loud.prefab.domainB\x06Prefabb\x06proto3"
8
+ descriptor_data = "\n\x0cprefab.proto\x12\x06prefab\"W\n\x14\x43onfigServicePointer\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x13\n\x0bstart_at_id\x18\x02 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x03 \x01(\x03\"\xca\x02\n\x0b\x43onfigValue\x12\r\n\x03int\x18\x01 \x01(\x03H\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x0f\n\x05\x62ytes\x18\x03 \x01(\x0cH\x00\x12\x10\n\x06\x64ouble\x18\x04 \x01(\x01H\x00\x12\x0e\n\x04\x62ool\x18\x05 \x01(\x08H\x00\x12\x31\n\x0fweighted_values\x18\x06 \x01(\x0b\x32\x16.prefab.WeightedValuesH\x00\x12\x33\n\x10limit_definition\x18\x07 \x01(\x0b\x32\x17.prefab.LimitDefinitionH\x00\x12%\n\tlog_level\x18\t \x01(\x0e\x32\x10.prefab.LogLevelH\x00\x12)\n\x0bstring_list\x18\n \x01(\x0b\x32\x12.prefab.StringListH\x00\x12%\n\tint_range\x18\x0b \x01(\x0b\x32\x10.prefab.IntRangeH\x00\x42\x06\n\x04type\"B\n\x08IntRange\x12\x12\n\x05start\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x10\n\x03\x65nd\x18\x02 \x01(\x03H\x01\x88\x01\x01\x42\x08\n\x06_startB\x06\n\x04_end\"\x1c\n\nStringList\x12\x0e\n\x06values\x18\x01 \x03(\t\"C\n\rWeightedValue\x12\x0e\n\x06weight\x18\x01 \x01(\x05\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"~\n\x0eWeightedValues\x12.\n\x0fweighted_values\x18\x01 \x03(\x0b\x32\x15.prefab.WeightedValue\x12\"\n\x15hash_by_property_name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x18\n\x16_hash_by_property_name\"h\n\x07\x43onfigs\x12\x1f\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x0e.prefab.Config\x12<\n\x16\x63onfig_service_pointer\x18\x02 \x01(\x0b\x32\x1c.prefab.ConfigServicePointer\"\xf7\x01\n\x06\x43onfig\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x12\n\nproject_id\x18\x02 \x01(\x03\x12\x0b\n\x03key\x18\x03 \x01(\t\x12%\n\nchanged_by\x18\x04 \x01(\x0b\x32\x11.prefab.ChangedBy\x12\x1f\n\x04rows\x18\x05 \x03(\x0b\x32\x11.prefab.ConfigRow\x12-\n\x10\x61llowable_values\x18\x06 \x03(\x0b\x32\x13.prefab.ConfigValue\x12\'\n\x0b\x63onfig_type\x18\x07 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x14\n\x07\x64raftId\x18\x08 \x01(\x03H\x00\x88\x01\x01\x42\n\n\x08_draftId\"+\n\tChangedBy\x12\x0f\n\x07user_id\x18\x01 \x01(\x03\x12\r\n\x05\x65mail\x18\x02 \x01(\t\"\xe4\x01\n\tConfigRow\x12\x1b\n\x0eproject_env_id\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12(\n\x06values\x18\x02 \x03(\x0b\x32\x18.prefab.ConditionalValue\x12\x35\n\nproperties\x18\x03 \x03(\x0b\x32!.prefab.ConfigRow.PropertiesEntry\x1a\x46\n\x0fPropertiesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x11\n\x0f_project_env_id\"[\n\x10\x43onditionalValue\x12#\n\x08\x63riteria\x18\x01 \x03(\x0b\x32\x11.prefab.Criterion\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x94\x03\n\tCriterion\x12\x15\n\rproperty_name\x18\x01 \x01(\t\x12\x35\n\x08operator\x18\x02 \x01(\x0e\x32#.prefab.Criterion.CriterionOperator\x12+\n\x0evalue_to_match\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\"\x8b\x02\n\x11\x43riterionOperator\x12\x0b\n\x07NOT_SET\x10\x00\x12\x11\n\rLOOKUP_KEY_IN\x10\x01\x12\x15\n\x11LOOKUP_KEY_NOT_IN\x10\x02\x12\n\n\x06IN_SEG\x10\x03\x12\x0e\n\nNOT_IN_SEG\x10\x04\x12\x0f\n\x0b\x41LWAYS_TRUE\x10\x05\x12\x12\n\x0ePROP_IS_ONE_OF\x10\x06\x12\x16\n\x12PROP_IS_NOT_ONE_OF\x10\x07\x12\x19\n\x15PROP_ENDS_WITH_ONE_OF\x10\x08\x12!\n\x1dPROP_DOES_NOT_END_WITH_ONE_OF\x10\t\x12\x16\n\x12HIERARCHICAL_MATCH\x10\n\x12\x10\n\x0cIN_INT_RANGE\x10\x0b\"\x89\x01\n\x07Loggers\x12\x1f\n\x07loggers\x18\x01 \x03(\x0b\x32\x0e.prefab.Logger\x12\x10\n\x08start_at\x18\x02 \x01(\x03\x12\x0e\n\x06\x65nd_at\x18\x03 \x01(\x03\x12\x15\n\rinstance_hash\x18\x04 \x01(\t\x12\x16\n\tnamespace\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\xd9\x01\n\x06Logger\x12\x13\n\x0blogger_name\x18\x01 \x01(\t\x12\x13\n\x06traces\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x13\n\x06\x64\x65\x62ugs\x18\x03 \x01(\x03H\x01\x88\x01\x01\x12\x12\n\x05infos\x18\x04 \x01(\x03H\x02\x88\x01\x01\x12\x12\n\x05warns\x18\x05 \x01(\x03H\x03\x88\x01\x01\x12\x13\n\x06\x65rrors\x18\x06 \x01(\x03H\x04\x88\x01\x01\x12\x13\n\x06\x66\x61tals\x18\x07 \x01(\x03H\x05\x88\x01\x01\x42\t\n\x07_tracesB\t\n\x07_debugsB\x08\n\x06_infosB\x08\n\x06_warnsB\t\n\x07_errorsB\t\n\x07_fatals\"\x16\n\x14LoggerReportResponse\"\xdb\x03\n\rLimitResponse\x12\x0e\n\x06passed\x18\x01 \x01(\x08\x12\x12\n\nexpires_at\x18\x02 \x01(\x03\x12\x16\n\x0e\x65nforced_group\x18\x03 \x01(\t\x12\x16\n\x0e\x63urrent_bucket\x18\x04 \x01(\x03\x12\x14\n\x0cpolicy_group\x18\x05 \x01(\t\x12;\n\x0bpolicy_name\x18\x06 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\x14\n\x0cpolicy_limit\x18\x07 \x01(\x05\x12\x0e\n\x06\x61mount\x18\x08 \x01(\x03\x12\x16\n\x0elimit_reset_at\x18\t \x01(\x03\x12\x39\n\x0csafety_level\x18\n \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"\xa9\x01\n\x10LimitPolicyNames\x12\x0b\n\x07NOT_SET\x10\x00\x12\x14\n\x10SECONDLY_ROLLING\x10\x01\x12\x14\n\x10MINUTELY_ROLLING\x10\x03\x12\x12\n\x0eHOURLY_ROLLING\x10\x05\x12\x11\n\rDAILY_ROLLING\x10\x07\x12\x13\n\x0fMONTHLY_ROLLING\x10\x08\x12\x0c\n\x08INFINITE\x10\t\x12\x12\n\x0eYEARLY_ROLLING\x10\n\"\x99\x02\n\x0cLimitRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x16\n\x0e\x61\x63quire_amount\x18\x02 \x01(\x05\x12\x0e\n\x06groups\x18\x03 \x03(\t\x12:\n\x0elimit_combiner\x18\x04 \x01(\x0e\x32\".prefab.LimitRequest.LimitCombiner\x12\x1e\n\x16\x61llow_partial_response\x18\x05 \x01(\x08\x12\x39\n\x0csafety_level\x18\x06 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"6\n\rLimitCombiner\x12\x0b\n\x07NOT_SET\x10\x00\x12\x0b\n\x07MINIMUM\x10\x01\x12\x0b\n\x07MAXIMUM\x10\x02\"/\n\nContextSet\x12!\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x0f.prefab.Context\"\x96\x01\n\x07\x43ontext\x12\x11\n\x04type\x18\x01 \x01(\tH\x00\x88\x01\x01\x12+\n\x06values\x18\x02 \x03(\x0b\x32\x1b.prefab.Context.ValuesEntry\x1a\x42\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.prefab.ConfigValue:\x02\x38\x01\x42\x07\n\x05_type\"\x93\x01\n\x08Identity\x12\x13\n\x06lookup\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x34\n\nattributes\x18\x02 \x03(\x0b\x32 .prefab.Identity.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_lookup\"\xc1\x01\n\x11\x43lientConfigValue\x12\x10\n\x03int\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x13\n\x06string\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x64ouble\x18\x03 \x01(\x01H\x02\x88\x01\x01\x12\x11\n\x04\x62ool\x18\x04 \x01(\x08H\x03\x88\x01\x01\x12(\n\tlog_level\x18\x05 \x01(\x0e\x32\x10.prefab.LogLevelH\x04\x88\x01\x01\x42\x06\n\x04_intB\t\n\x07_stringB\t\n\x07_doubleB\x07\n\x05_boolB\x0c\n\n_log_level\"\x94\x01\n\x11\x43onfigEvaluations\x12\x35\n\x06values\x18\x01 \x03(\x0b\x32%.prefab.ConfigEvaluations.ValuesEntry\x1aH\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.prefab.ClientConfigValue:\x02\x38\x01\"\xa8\x02\n\x0fLimitDefinition\x12;\n\x0bpolicy_name\x18\x02 \x01(\x0e\x32&.prefab.LimitResponse.LimitPolicyNames\x12\r\n\x05limit\x18\x03 \x01(\x05\x12\r\n\x05\x62urst\x18\x04 \x01(\x05\x12\x12\n\naccount_id\x18\x05 \x01(\x03\x12\x15\n\rlast_modified\x18\x06 \x01(\x03\x12\x12\n\nreturnable\x18\x07 \x01(\x08\x12\x39\n\x0csafety_level\x18\x08 \x01(\x0e\x32#.prefab.LimitDefinition.SafetyLevel\"@\n\x0bSafetyLevel\x12\x0b\n\x07NOT_SET\x10\x00\x12\x12\n\x0eL4_BEST_EFFORT\x10\x04\x12\x10\n\x0cL5_BOMBPROOF\x10\x05\"@\n\x10LimitDefinitions\x12,\n\x0b\x64\x65\x66initions\x18\x01 \x03(\x0b\x32\x17.prefab.LimitDefinition\"\x8a\x01\n\x0f\x42ufferedRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x14\n\x0c\x63ontent_type\x18\x06 \x01(\t\x12\x0c\n\x04\x66ifo\x18\x07 \x01(\x08\"\x94\x01\n\x0c\x42\x61tchRequest\x12\x12\n\naccount_id\x18\x01 \x01(\x03\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0b\n\x03uri\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\x12\x14\n\x0climit_groups\x18\x05 \x03(\t\x12\x16\n\x0e\x62\x61tch_template\x18\x06 \x01(\t\x12\x17\n\x0f\x62\x61tch_separator\x18\x07 \x01(\t\" \n\rBasicResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\"3\n\x10\x43reationResponse\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0e\n\x06new_id\x18\x02 \x01(\x03\"h\n\x07IdBlock\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\r\n\x05start\x18\x04 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x03\"a\n\x0eIdBlockRequest\x12\x12\n\nproject_id\x18\x01 \x01(\x03\x12\x16\n\x0eproject_env_id\x18\x02 \x01(\x03\x12\x15\n\rsequence_name\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x03\"\x8a\x01\n\x0c\x43ontextShape\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x39\n\x0b\x66ield_types\x18\x02 \x03(\x0b\x32$.prefab.ContextShape.FieldTypesEntry\x1a\x31\n\x0f\x46ieldTypesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"[\n\rContextShapes\x12$\n\x06shapes\x18\x01 \x03(\x0b\x32\x14.prefab.ContextShape\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"C\n\rEvaluatedKeys\x12\x0c\n\x04keys\x18\x01 \x03(\t\x12\x16\n\tnamespace\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0c\n\n_namespace\"\x93\x01\n\x0f\x45valuatedConfig\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x16\n\x0e\x63onfig_version\x18\x02 \x01(\x03\x12#\n\x06result\x18\x03 \x01(\x0b\x32\x13.prefab.ConfigValue\x12#\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x12.prefab.ContextSet\x12\x11\n\ttimestamp\x18\x05 \x01(\x03\"<\n\x10\x45valuatedConfigs\x12(\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32\x17.prefab.EvaluatedConfig\"\xb1\x03\n\x17\x43onfigEvaluationCounter\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x11\n\tconfig_id\x18\x02 \x01(\x03\x12\x1b\n\x0eselected_index\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x30\n\x0eselected_value\x18\x04 \x01(\x0b\x32\x13.prefab.ConfigValueH\x01\x88\x01\x01\x12\x1d\n\x10\x63onfig_row_index\x18\x05 \x01(\rH\x02\x88\x01\x01\x12$\n\x17\x63onditional_value_index\x18\x06 \x01(\rH\x03\x88\x01\x01\x12!\n\x14weighted_value_index\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x36\n\x06reason\x18\x08 \x01(\x0e\x32&.prefab.ConfigEvaluationCounter.Reason\"\x15\n\x06Reason\x12\x0b\n\x07UNKNOWN\x10\x00\x42\x11\n\x0f_selected_indexB\x11\n\x0f_selected_valueB\x13\n\x11_config_row_indexB\x1a\n\x18_conditional_value_indexB\x17\n\x15_weighted_value_index\"{\n\x17\x43onfigEvaluationSummary\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x04type\x18\x02 \x01(\x0e\x32\x12.prefab.ConfigType\x12\x31\n\x08\x63ounters\x18\x03 \x03(\x0b\x32\x1f.prefab.ConfigEvaluationCounter\"k\n\x19\x43onfigEvaluationSummaries\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\x12\x32\n\tsummaries\x18\x03 \x03(\x0b\x32\x1f.prefab.ConfigEvaluationSummary\"\xb5\x01\n\x0eTelemetryEvent\x12\x36\n\tsummaries\x18\x02 \x01(\x0b\x32!.prefab.ConfigEvaluationSummariesH\x00\x12\x33\n\x10\x65xample_contexts\x18\x03 \x01(\x0b\x32\x17.prefab.ExampleContextsH\x00\x12+\n\x0c\x63lient_stats\x18\x04 \x01(\x0b\x32\x13.prefab.ClientStatsH\x00\x42\t\n\x07payload\"P\n\x0fTelemetryEvents\x12\x15\n\rinstance_hash\x18\x01 \x01(\t\x12&\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x16.prefab.TelemetryEvent\"*\n\x17TelemetryEventsResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\";\n\x0f\x45xampleContexts\x12(\n\x08\x65xamples\x18\x01 \x03(\x0b\x32\x16.prefab.ExampleContext\"K\n\x0e\x45xampleContext\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12&\n\ncontextSet\x18\x02 \x01(\x0b\x32\x12.prefab.ContextSet\"F\n\x0b\x43lientStats\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\x12\x1b\n\x13\x64ropped_event_count\x18\x03 \x01(\x04*u\n\nConfigType\x12\x17\n\x13NOT_SET_CONFIG_TYPE\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\x10\n\x0c\x46\x45\x41TURE_FLAG\x10\x02\x12\r\n\tLOG_LEVEL\x10\x03\x12\x0b\n\x07SEGMENT\x10\x04\x12\x14\n\x10LIMIT_DEFINITION\x10\x05*a\n\x08LogLevel\x12\x15\n\x11NOT_SET_LOG_LEVEL\x10\x00\x12\t\n\x05TRACE\x10\x01\x12\t\n\x05\x44\x45\x42UG\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\x08\n\x04WARN\x10\x05\x12\t\n\x05\x45RROR\x10\x06\x12\t\n\x05\x46\x41TAL\x10\t*G\n\tOnFailure\x12\x0b\n\x07NOT_SET\x10\x00\x12\x10\n\x0cLOG_AND_PASS\x10\x01\x12\x10\n\x0cLOG_AND_FAIL\x10\x02\x12\t\n\x05THROW\x10\x03\x42\x1d\n\x13\x63loud.prefab.domainB\x06Prefabb\x06proto3"
9
9
 
10
10
  pool = Google::Protobuf::DescriptorPool.generated_pool
11
11
 
@@ -71,6 +71,16 @@ module PrefabProto
71
71
  EvaluatedKeys = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.EvaluatedKeys").msgclass
72
72
  EvaluatedConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.EvaluatedConfig").msgclass
73
73
  EvaluatedConfigs = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.EvaluatedConfigs").msgclass
74
+ ConfigEvaluationCounter = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluationCounter").msgclass
75
+ ConfigEvaluationCounter::Reason = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluationCounter.Reason").enummodule
76
+ ConfigEvaluationSummary = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluationSummary").msgclass
77
+ ConfigEvaluationSummaries = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluationSummaries").msgclass
78
+ TelemetryEvent = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.TelemetryEvent").msgclass
79
+ TelemetryEvents = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.TelemetryEvents").msgclass
80
+ TelemetryEventsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.TelemetryEventsResponse").msgclass
81
+ ExampleContexts = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ExampleContexts").msgclass
82
+ ExampleContext = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ExampleContext").msgclass
83
+ ClientStats = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ClientStats").msgclass
74
84
  ConfigType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigType").enummodule
75
85
  LogLevel = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LogLevel").enummodule
76
86
  OnFailure = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.OnFailure").enummodule
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: prefab-cloud-ruby 0.24.5 ruby lib
5
+ # stub: prefab-cloud-ruby 1.0.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.24.5"
9
+ s.version = "1.0.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Jeff Dwyer".freeze]
14
- s.date = "2023-07-10"
14
+ s.date = "2023-08-10"
15
15
  s.description = "Feature Flags, Live Config, and Dynamic Log Levels as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.executables = ["console".freeze]
@@ -52,8 +52,9 @@ Gem::Specification.new do |s|
52
52
  "lib/prefab/errors/initialization_timeout_error.rb",
53
53
  "lib/prefab/errors/invalid_api_key_error.rb",
54
54
  "lib/prefab/errors/missing_default_error.rb",
55
- "lib/prefab/evaluated_configs_aggregator.rb",
56
- "lib/prefab/evaluated_keys_aggregator.rb",
55
+ "lib/prefab/evaluation.rb",
56
+ "lib/prefab/evaluation_summary_aggregator.rb",
57
+ "lib/prefab/example_contexts_aggregator.rb",
57
58
  "lib/prefab/exponential_backoff.rb",
58
59
  "lib/prefab/feature_flag_client.rb",
59
60
  "lib/prefab/http_connection.rb",
@@ -62,10 +63,9 @@ Gem::Specification.new do |s|
62
63
  "lib/prefab/log_path_aggregator.rb",
63
64
  "lib/prefab/logger_client.rb",
64
65
  "lib/prefab/murmer3.rb",
65
- "lib/prefab/noop_cache.rb",
66
- "lib/prefab/noop_stats.rb",
67
66
  "lib/prefab/options.rb",
68
67
  "lib/prefab/periodic_sync.rb",
68
+ "lib/prefab/rate_limit_cache.rb",
69
69
  "lib/prefab/resolved_config_presenter.rb",
70
70
  "lib/prefab/sse_logger.rb",
71
71
  "lib/prefab/time_helpers.rb",
@@ -77,6 +77,10 @@ Gem::Specification.new do |s|
77
77
  "test/.prefab.unit_tests.config.yaml",
78
78
  "test/integration_test.rb",
79
79
  "test/integration_test_helpers.rb",
80
+ "test/support/common_helpers.rb",
81
+ "test/support/mock_base_client.rb",
82
+ "test/support/mock_config_client.rb",
83
+ "test/support/mock_config_loader.rb",
80
84
  "test/test_client.rb",
81
85
  "test/test_config_client.rb",
82
86
  "test/test_config_loader.rb",
@@ -86,8 +90,8 @@ Gem::Specification.new do |s|
86
90
  "test/test_context_shape.rb",
87
91
  "test/test_context_shape_aggregator.rb",
88
92
  "test/test_criteria_evaluator.rb",
89
- "test/test_evaluated_configs_aggregator.rb",
90
- "test/test_evaluated_keys_aggregator.rb",
93
+ "test/test_evaluation_summary_aggregator.rb",
94
+ "test/test_example_contexts_aggregator.rb",
91
95
  "test/test_exponential_backoff.rb",
92
96
  "test/test_feature_flag_client.rb",
93
97
  "test/test_helper.rb",
@@ -96,6 +100,7 @@ Gem::Specification.new do |s|
96
100
  "test/test_log_path_aggregator.rb",
97
101
  "test/test_logger.rb",
98
102
  "test/test_options.rb",
103
+ "test/test_rate_limit_cache.rb",
99
104
  "test/test_weighted_value_resolver.rb"
100
105
  ]
101
106
  s.homepage = "http://github.com/prefab-cloud/prefab-cloud-ruby".freeze
@@ -18,8 +18,6 @@ class IntegrationTest
18
18
  :raise
19
19
  elsif @expected[:value].nil?
20
20
  :nil
21
- elsif @func == :feature_is_on_for?
22
- :feature_flag
23
21
  else
24
22
  :simple_equality
25
23
  end
@@ -60,7 +58,7 @@ class IntegrationTest
60
58
  end
61
59
 
62
60
  def parse_ff_input(input)
63
- [input['flag'], input['context']]
61
+ [input['flag'], input['default'], input['context']]
64
62
  end
65
63
 
66
64
  def parse_expected(expected)
@@ -14,7 +14,6 @@ module IntegrationTestHelpers
14
14
  raise message if RAISE_IF_NO_TESTS_FOUND
15
15
 
16
16
  puts message
17
-
18
17
  end
19
18
 
20
19
  files