prefab-cloud-ruby 0.20.0 → 0.22.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc.sample +3 -0
  3. data/.github/workflows/ruby.yml +5 -1
  4. data/.gitmodules +3 -0
  5. data/Gemfile +14 -12
  6. data/Gemfile.lock +24 -14
  7. data/README.md +12 -10
  8. data/Rakefile +13 -14
  9. data/VERSION +1 -1
  10. data/lib/prefab/auth_interceptor.rb +2 -1
  11. data/lib/prefab/cancellable_interceptor.rb +8 -7
  12. data/lib/prefab/client.rb +52 -27
  13. data/lib/prefab/config_client.rb +59 -70
  14. data/lib/prefab/config_loader.rb +7 -114
  15. data/lib/prefab/config_resolver.rb +27 -57
  16. data/lib/prefab/config_value_unwrapper.rb +23 -0
  17. data/lib/prefab/criteria_evaluator.rb +96 -0
  18. data/lib/prefab/errors/invalid_api_key_error.rb +1 -1
  19. data/lib/prefab/feature_flag_client.rb +13 -145
  20. data/lib/prefab/internal_logger.rb +7 -6
  21. data/lib/prefab/local_config_parser.rb +110 -0
  22. data/lib/prefab/log_path_collector.rb +98 -0
  23. data/lib/prefab/logger_client.rb +46 -44
  24. data/lib/prefab/murmer3.rb +3 -4
  25. data/lib/prefab/noop_cache.rb +5 -7
  26. data/lib/prefab/noop_stats.rb +2 -3
  27. data/lib/prefab/options.rb +32 -11
  28. data/lib/prefab/ratelimit_client.rb +11 -13
  29. data/lib/prefab/sse_logger.rb +3 -2
  30. data/lib/prefab/weighted_value_resolver.rb +42 -0
  31. data/lib/prefab/yaml_config_parser.rb +32 -0
  32. data/lib/prefab-cloud-ruby.rb +7 -2
  33. data/lib/prefab_pb.rb +70 -43
  34. data/lib/prefab_services_pb.rb +14 -1
  35. data/prefab-cloud-ruby.gemspec +33 -19
  36. data/test/.prefab.unit_tests.config.yaml +3 -2
  37. data/test/integration_test.rb +98 -0
  38. data/test/integration_test_helpers.rb +37 -0
  39. data/test/test_client.rb +56 -31
  40. data/test/test_config_client.rb +21 -20
  41. data/test/test_config_loader.rb +48 -37
  42. data/test/test_config_resolver.rb +312 -135
  43. data/test/test_config_value_unwrapper.rb +83 -0
  44. data/test/test_criteria_evaluator.rb +533 -0
  45. data/test/test_feature_flag_client.rb +35 -347
  46. data/test/test_helper.rb +18 -14
  47. data/test/test_integration.rb +33 -0
  48. data/test/test_local_config_parser.rb +78 -0
  49. data/test/test_log_path_collector.rb +56 -0
  50. data/test/test_logger.rb +52 -51
  51. data/test/test_options.rb +32 -0
  52. data/test/test_weighted_value_resolver.rb +65 -0
  53. metadata +30 -16
  54. data/lib/prefab/config_helper.rb +0 -31
  55. data/run_test_harness_server.sh +0 -8
  56. data/test/harness_server.rb +0 -64
@@ -17,45 +17,53 @@ module Prefab
17
17
  attr_reader :prefab_config_override_dir
18
18
  attr_reader :prefab_config_classpath_dir
19
19
  attr_reader :prefab_envs
20
+ attr_reader :collect_sync_interval
20
21
 
21
22
  DEFAULT_LOG_FORMATTER = proc { |severity, datetime, progname, msg|
22
- "#{severity.ljust(5)} #{datetime}:#{" " if progname}#{progname} #{msg}\n"
23
+ "#{severity.ljust(5)} #{datetime}:#{' ' if progname}#{progname} #{msg}\n"
23
24
  }
24
25
 
25
26
  module ON_INITIALIZATION_FAILURE
26
27
  RAISE = 1
27
28
  RETURN = 2
28
29
  end
30
+
29
31
  module ON_NO_DEFAULT
30
32
  RAISE = 1
31
33
  RETURN_NIL = 2
32
34
  end
35
+
33
36
  module DATASOURCES
34
37
  ALL = 1
35
38
  LOCAL_ONLY = 2
36
39
  end
37
40
 
38
- def initialize(
41
+ DEFAULT_MAX_PATHS = 1_000
42
+ DEFAULT_SYNC_INTERVAL = 60
43
+
44
+ private def init(
39
45
  api_key: ENV['PREFAB_API_KEY'],
40
46
  logdev: $stdout,
41
47
  stats: NoopStats.new, # receives increment("prefab.limitcheck", {:tags=>["policy_group:page_view", "pass:true"]})
42
48
  shared_cache: NoopCache.new, # Something that quacks like Rails.cache ideally memcached
43
- namespace: "",
49
+ namespace: '',
44
50
  log_formatter: DEFAULT_LOG_FORMATTER,
45
51
  log_prefix: nil,
46
- prefab_api_url: ENV["PREFAB_API_URL"] || 'https://api.prefab.cloud',
47
- prefab_grpc_url: ENV["PREFAB_GRPC_URL"] || 'grpc.prefab.cloud:443',
52
+ prefab_api_url: ENV['PREFAB_API_URL'] || 'https://api.prefab.cloud',
53
+ prefab_grpc_url: ENV['PREFAB_GRPC_URL'] || 'grpc.prefab.cloud:443',
48
54
  on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
49
55
  initialization_timeout_sec: 10, # how long to wait before on_init_failure
50
- on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, #options :unlock_and_continue, :lock_and_keep_trying, :raise
56
+ on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, # options :unlock_and_continue, :lock_and_keep_trying, :raise
51
57
  # new_config_callback: nil, #callback method
52
58
  # live_override_url: nil,
53
- prefab_datasources: ENV['PREFAB_DATASOURCES'] == "LOCAL_ONLY" ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
59
+ prefab_datasources: ENV['PREFAB_DATASOURCES'] == 'LOCAL_ONLY' ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
54
60
  prefab_config_override_dir: Dir.home,
55
- prefab_config_classpath_dir: ".",
56
- prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(",")
61
+ prefab_config_classpath_dir: '.',
62
+ prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(','),
63
+ collect_logs: true,
64
+ collect_max_paths: DEFAULT_MAX_PATHS,
65
+ collect_sync_interval: DEFAULT_SYNC_INTERVAL
57
66
  )
58
- # debugger
59
67
  @api_key = api_key
60
68
  @logdev = logdev
61
69
  @stats = stats
@@ -72,15 +80,28 @@ module Prefab
72
80
  @prefab_config_classpath_dir = prefab_config_classpath_dir
73
81
  @prefab_config_override_dir = prefab_config_override_dir
74
82
  @prefab_envs = Array(prefab_envs)
83
+ @collect_logs = collect_logs
84
+ @collect_max_paths = collect_max_paths
85
+ @collect_sync_interval = collect_sync_interval
86
+ end
87
+
88
+ def initialize(options = {})
89
+ init(**options)
75
90
  end
76
91
 
77
92
  def local_only?
78
93
  @prefab_datasources == DATASOURCES::LOCAL_ONLY
79
94
  end
80
95
 
96
+ def collect_max_paths
97
+ return 0 if !@collect_logs || local_only?
98
+
99
+ @collect_max_paths
100
+ end
101
+
81
102
  # https://api.prefab.cloud -> https://api-prefab-cloud.global.ssl.fastly.net
82
103
  def url_for_api_cdn
83
- ENV['PREFAB_CDN_URL'] || "#{@prefab_api_url.gsub(/\./, "-")}.global.ssl.fastly.net"
104
+ ENV['PREFAB_CDN_URL'] || "#{@prefab_api_url.gsub(/\./, '-')}.global.ssl.fastly.net"
84
105
  end
85
106
  end
86
107
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Prefab
3
4
  class RateLimitClient
4
-
5
5
  def initialize(base_client, timeout)
6
6
  @timeout = timeout
7
7
  @base_client = base_client
@@ -9,14 +9,14 @@ module Prefab
9
9
 
10
10
  def pass?(group)
11
11
  result = acquire([group], 1)
12
- return result.passed
12
+ result.passed
13
13
  end
14
14
 
15
15
  def acquire(groups, acquire_amount, allow_partial_response: false, on_error: :log_and_pass)
16
- expiry_cache_key = "prefab.ratelimit.expiry:#{groups.join(".")}"
16
+ expiry_cache_key = "prefab.ratelimit.expiry:#{groups.join('.')}"
17
17
  expiry = @base_client.shared_cache.read(expiry_cache_key)
18
18
  if !expiry.nil? && Integer(expiry) > Time.now.utc.to_f * 1000
19
- @base_client.stats.increment("prefab.ratelimit.limitcheck.expirycache.hit", tags: [])
19
+ @base_client.stats.increment('prefab.ratelimit.limitcheck.expirycache.hit', tags: [])
20
20
  return Prefab::LimitResponse.new(passed: false, amount: 0)
21
21
  end
22
22
 
@@ -27,16 +27,17 @@ module Prefab
27
27
  allow_partial_response: allow_partial_response
28
28
  )
29
29
 
30
- result = @base_client.request Prefab::RateLimitService, :limit_check, req_options: {timeout: @timeout}, params: req
30
+ result = @base_client.request Prefab::RateLimitService, :limit_check, req_options: { timeout: @timeout },
31
+ params: req
31
32
 
32
33
  reset = result.limit_reset_at
33
34
  @base_client.shared_cache.write(expiry_cache_key, reset) unless reset < 1 # protobuf default int to 0
34
35
 
35
- @base_client.stats.increment("prefab.ratelimit.limitcheck", tags: ["policy_group:#{result.policy_group}", "pass:#{result.passed}"])
36
+ @base_client.stats.increment('prefab.ratelimit.limitcheck',
37
+ tags: ["policy_group:#{result.policy_group}", "pass:#{result.passed}"])
36
38
 
37
39
  result
38
-
39
- rescue => e
40
+ rescue StandardError => e
40
41
  handle_error(e, on_error, groups)
41
42
  end
42
43
 
@@ -48,9 +49,7 @@ module Prefab
48
49
  limit: limit,
49
50
  burst: burst
50
51
  )
51
- unless safety_level.nil?
52
- limit_definition.safety_level = safety_level
53
- end
52
+ limit_definition.safety_level = safety_level unless safety_level.nil?
54
53
  config_value = Prefab::ConfigValue.new(limit_definition: limit_definition)
55
54
  config_delta = Prefab::ConfigClient.value_to_delta(key, config_value)
56
55
  upsert_req = Prefab::UpsertRequest.new(config_delta: config_delta)
@@ -61,7 +60,7 @@ module Prefab
61
60
  private
62
61
 
63
62
  def handle_error(e, on_error, groups)
64
- @base_client.stats.increment("prefab.ratelimit.error", tags: ["type:limit"])
63
+ @base_client.stats.increment('prefab.ratelimit.error', tags: ['type:limit'])
65
64
 
66
65
  message = "ratelimit for #{groups} error: #{e.message}"
67
66
  case on_error
@@ -77,4 +76,3 @@ module Prefab
77
76
  end
78
77
  end
79
78
  end
80
-
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Prefab
3
4
  class SseLogger < InternalLogger
4
5
  def initialize(logger)
5
- super("sse", logger)
6
+ super('sse', logger)
6
7
  end
7
8
 
8
9
  # The SSE::Client warns on a perfectly normal stream disconnect, recast to info
9
- def warn(progname = nil, &block)
10
+ def warn(progname = nil)
10
11
  @logger.log_internal yield, @path, progname, INFO
11
12
  end
12
13
  end
@@ -0,0 +1,42 @@
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, lookup_key)
8
+ @weights = weights
9
+ @config_key = config_key
10
+ @lookup_key = lookup_key
11
+ end
12
+
13
+ def resolve
14
+ percent = @lookup_key ? user_percent : rand
15
+
16
+ index = variant_index(percent)
17
+
18
+ @weights[index]
19
+ end
20
+
21
+ def user_percent
22
+ to_hash = "#{@config_key}#{@lookup_key}"
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
@@ -0,0 +1,32 @@
1
+ require 'yaml'
2
+
3
+ module Prefab
4
+ class YAMLConfigParser
5
+ def initialize(file, client)
6
+ @file = file
7
+ @client = client
8
+ end
9
+
10
+ def merge(config)
11
+ yaml = load
12
+
13
+ yaml.each do |k, v|
14
+ config = Prefab::LocalConfigParser.parse(k, v, config, @file)
15
+ end
16
+
17
+ config
18
+ end
19
+
20
+ private
21
+
22
+ def load
23
+ if File.exist?(@file)
24
+ @client.log_internal ::Logger::INFO, "Load #{@file}"
25
+ YAML.load_file(@file)
26
+ else
27
+ @client.log_internal ::Logger::INFO, "No file #{@file}"
28
+ {}
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require "concurrent/atomics"
2
+
3
+ require 'concurrent/atomics'
3
4
  require 'concurrent'
4
5
  require 'faraday'
5
6
  require 'openssl'
@@ -14,8 +15,12 @@ require 'prefab_services_pb'
14
15
  require 'prefab/options'
15
16
  require 'prefab/internal_logger'
16
17
  require 'prefab/sse_logger'
17
- require 'prefab/config_helper'
18
+ require 'prefab/weighted_value_resolver'
19
+ require 'prefab/config_value_unwrapper'
20
+ require 'prefab/criteria_evaluator'
18
21
  require 'prefab/config_loader'
22
+ require 'prefab/local_config_parser'
23
+ require 'prefab/yaml_config_parser'
19
24
  require 'prefab/config_resolver'
20
25
  require 'prefab/client'
21
26
  require 'prefab/ratelimit_client'
data/lib/prefab_pb.rb CHANGED
@@ -17,12 +17,22 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
17
17
  optional :bytes, :bytes, 3
18
18
  optional :double, :double, 4
19
19
  optional :bool, :bool, 5
20
- optional :feature_flag, :message, 6, "prefab.FeatureFlag"
20
+ optional :weighted_values, :message, 6, "prefab.WeightedValues"
21
21
  optional :limit_definition, :message, 7, "prefab.LimitDefinition"
22
- optional :segment, :message, 8, "prefab.Segment"
23
22
  optional :log_level, :enum, 9, "prefab.LogLevel"
23
+ optional :string_list, :message, 10, "prefab.StringList"
24
24
  end
25
25
  end
26
+ add_message "prefab.StringList" do
27
+ repeated :values, :string, 1
28
+ end
29
+ add_message "prefab.WeightedValue" do
30
+ optional :weight, :int32, 1
31
+ optional :value, :message, 2, "prefab.ConfigValue"
32
+ end
33
+ add_message "prefab.WeightedValues" do
34
+ repeated :weighted_values, :message, 1, "prefab.WeightedValue"
35
+ end
26
36
  add_message "prefab.Configs" do
27
37
  repeated :configs, :message, 1, "prefab.Config"
28
38
  optional :config_service_pointer, :message, 2, "prefab.ConfigServicePointer"
@@ -31,14 +41,24 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
31
41
  optional :id, :int64, 1
32
42
  optional :project_id, :int64, 2
33
43
  optional :key, :string, 3
34
- optional :changed_by, :string, 4
44
+ optional :changed_by, :message, 4, "prefab.ChangedBy"
35
45
  repeated :rows, :message, 5, "prefab.ConfigRow"
36
- repeated :variants, :message, 6, "prefab.FeatureFlagVariant"
46
+ repeated :allowable_values, :message, 6, "prefab.ConfigValue"
47
+ optional :config_type, :enum, 7, "prefab.ConfigType"
48
+ proto3_optional :draftId, :int64, 8
49
+ end
50
+ add_message "prefab.ChangedBy" do
51
+ optional :user_id, :int64, 1
52
+ optional :email, :string, 2
37
53
  end
38
54
  add_message "prefab.ConfigRow" do
39
- optional :project_env_id, :int64, 1
40
- optional :namespace, :string, 2
41
- optional :value, :message, 3, "prefab.ConfigValue"
55
+ proto3_optional :project_env_id, :int64, 1
56
+ repeated :values, :message, 2, "prefab.ConditionalValue"
57
+ map :properties, :string, :message, 3, "prefab.ConfigValue"
58
+ end
59
+ add_message "prefab.ConditionalValue" do
60
+ repeated :criteria, :message, 1, "prefab.Criterion"
61
+ optional :value, :message, 2, "prefab.ConfigValue"
42
62
  end
43
63
  add_message "prefab.LimitResponse" do
44
64
  optional :passed, :bool, 1
@@ -75,20 +95,12 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
75
95
  value :MINIMUM, 1
76
96
  value :MAXIMUM, 2
77
97
  end
78
- add_message "prefab.FeatureFlagVariant" do
79
- proto3_optional :int, :int64, 1
80
- proto3_optional :string, :string, 2
81
- proto3_optional :double, :double, 3
82
- proto3_optional :bool, :bool, 4
83
- optional :name, :string, 5
84
- optional :description, :string, 6
85
- end
86
- add_message "prefab.Criteria" do
87
- optional :property, :string, 1
88
- optional :operator, :enum, 2, "prefab.Criteria.CriteriaOperator"
89
- repeated :values, :string, 3
98
+ add_message "prefab.Criterion" do
99
+ optional :property_name, :string, 1
100
+ optional :operator, :enum, 2, "prefab.Criterion.CriterionOperator"
101
+ optional :value_to_match, :message, 3, "prefab.ConfigValue"
90
102
  end
91
- add_enum "prefab.Criteria.CriteriaOperator" do
103
+ add_enum "prefab.Criterion.CriterionOperator" do
92
104
  value :NOT_SET, 0
93
105
  value :LOOKUP_KEY_IN, 1
94
106
  value :LOOKUP_KEY_NOT_IN, 2
@@ -99,22 +111,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
99
111
  value :PROP_IS_NOT_ONE_OF, 7
100
112
  value :PROP_ENDS_WITH_ONE_OF, 8
101
113
  value :PROP_DOES_NOT_END_WITH_ONE_OF, 9
102
- end
103
- add_message "prefab.Rule" do
104
- optional :criteria, :message, 1, "prefab.Criteria"
105
- repeated :variant_weights, :message, 2, "prefab.VariantWeight"
106
- end
107
- add_message "prefab.Segment" do
108
- repeated :criterion, :message, 1, "prefab.Criteria"
109
- end
110
- add_message "prefab.VariantWeight" do
111
- optional :weight, :int32, 1
112
- optional :variant_idx, :int32, 2
113
- end
114
- add_message "prefab.FeatureFlag" do
115
- optional :active, :bool, 1
116
- optional :inactive_variant_idx, :int32, 2
117
- repeated :rules, :message, 5, "prefab.Rule"
114
+ value :HIERARCHICAL_MATCH, 10
118
115
  end
119
116
  add_message "prefab.Identity" do
120
117
  proto3_optional :lookup, :string, 1
@@ -184,6 +181,32 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
184
181
  optional :sequence_name, :string, 3
185
182
  optional :size, :int64, 4
186
183
  end
184
+ add_message "prefab.Loggers" do
185
+ repeated :loggers, :message, 1, "prefab.Logger"
186
+ optional :start_at, :int64, 2
187
+ optional :end_at, :int64, 3
188
+ optional :instance_hash, :string, 4
189
+ proto3_optional :namespace, :string, 5
190
+ end
191
+ add_message "prefab.Logger" do
192
+ optional :logger_name, :string, 1
193
+ proto3_optional :traces, :int64, 2
194
+ proto3_optional :debugs, :int64, 3
195
+ proto3_optional :infos, :int64, 4
196
+ proto3_optional :warns, :int64, 5
197
+ proto3_optional :errors, :int64, 6
198
+ proto3_optional :fatals, :int64, 7
199
+ end
200
+ add_message "prefab.LoggerReportResponse" do
201
+ end
202
+ add_enum "prefab.ConfigType" do
203
+ value :NOT_SET_CONFIG_TYPE, 0
204
+ value :CONFIG, 1
205
+ value :FEATURE_FLAG, 2
206
+ value :LOG_LEVEL, 3
207
+ value :SEGMENT, 4
208
+ value :LIMIT_DEFINITION, 5
209
+ end
187
210
  add_enum "prefab.LogLevel" do
188
211
  value :NOT_SET_LOG_LEVEL, 0
189
212
  value :TRACE, 1
@@ -205,20 +228,20 @@ end
205
228
  module Prefab
206
229
  ConfigServicePointer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigServicePointer").msgclass
207
230
  ConfigValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigValue").msgclass
231
+ StringList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.StringList").msgclass
232
+ WeightedValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.WeightedValue").msgclass
233
+ WeightedValues = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.WeightedValues").msgclass
208
234
  Configs = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Configs").msgclass
209
235
  Config = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Config").msgclass
236
+ ChangedBy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ChangedBy").msgclass
210
237
  ConfigRow = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigRow").msgclass
238
+ ConditionalValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConditionalValue").msgclass
211
239
  LimitResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitResponse").msgclass
212
240
  LimitResponse::LimitPolicyNames = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitResponse.LimitPolicyNames").enummodule
213
241
  LimitRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitRequest").msgclass
214
242
  LimitRequest::LimitCombiner = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitRequest.LimitCombiner").enummodule
215
- FeatureFlagVariant = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.FeatureFlagVariant").msgclass
216
- Criteria = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criteria").msgclass
217
- Criteria::CriteriaOperator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criteria.CriteriaOperator").enummodule
218
- Rule = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Rule").msgclass
219
- Segment = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Segment").msgclass
220
- VariantWeight = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.VariantWeight").msgclass
221
- FeatureFlag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.FeatureFlag").msgclass
243
+ Criterion = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criterion").msgclass
244
+ Criterion::CriterionOperator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criterion.CriterionOperator").enummodule
222
245
  Identity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Identity").msgclass
223
246
  ClientConfigValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ClientConfigValue").msgclass
224
247
  ConfigEvaluations = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluations").msgclass
@@ -231,6 +254,10 @@ module Prefab
231
254
  CreationResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.CreationResponse").msgclass
232
255
  IdBlock = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.IdBlock").msgclass
233
256
  IdBlockRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.IdBlockRequest").msgclass
257
+ Loggers = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Loggers").msgclass
258
+ Logger = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Logger").msgclass
259
+ LoggerReportResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LoggerReportResponse").msgclass
260
+ ConfigType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigType").enummodule
234
261
  LogLevel = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LogLevel").enummodule
235
262
  OnFailure = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.OnFailure").enummodule
236
263
  end
@@ -1,4 +1,3 @@
1
- # frozen_string_literal: true
2
1
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
2
  # Source: prefab.proto for package 'prefab'
4
3
 
@@ -62,6 +61,20 @@ module Prefab
62
61
  rpc :GetAll, ::Prefab::Identity, ::Prefab::ConfigEvaluations
63
62
  end
64
63
 
64
+ Stub = Service.rpc_stub_class
65
+ end
66
+ module LoggerReportingService
67
+ class Service
68
+
69
+ include ::GRPC::GenericService
70
+
71
+ self.marshal_class_method = :encode
72
+ self.unmarshal_class_method = :decode
73
+ self.service_name = 'prefab.LoggerReportingService'
74
+
75
+ rpc :Send, ::Prefab::Loggers, ::Prefab::LoggerReportResponse
76
+ end
77
+
65
78
  Stub = Service.rpc_stub_class
66
79
  end
67
80
  end
@@ -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.20.0 ruby lib
5
+ # stub: prefab-cloud-ruby 0.22.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.20.0"
9
+ s.version = "0.22.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 = "2022-12-02"
14
+ s.date = "2023-03-15"
15
15
  s.description = "RateLimits & Config as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -20,7 +20,9 @@ Gem::Specification.new do |s|
20
20
  ]
21
21
  s.files = [
22
22
  ".envrc",
23
+ ".envrc.sample",
23
24
  ".github/workflows/ruby.yml",
25
+ ".gitmodules",
24
26
  ".tool-versions",
25
27
  "CODEOWNERS",
26
28
  "Gemfile",
@@ -35,15 +37,18 @@ Gem::Specification.new do |s|
35
37
  "lib/prefab/cancellable_interceptor.rb",
36
38
  "lib/prefab/client.rb",
37
39
  "lib/prefab/config_client.rb",
38
- "lib/prefab/config_helper.rb",
39
40
  "lib/prefab/config_loader.rb",
40
41
  "lib/prefab/config_resolver.rb",
42
+ "lib/prefab/config_value_unwrapper.rb",
43
+ "lib/prefab/criteria_evaluator.rb",
41
44
  "lib/prefab/error.rb",
42
45
  "lib/prefab/errors/initialization_timeout_error.rb",
43
46
  "lib/prefab/errors/invalid_api_key_error.rb",
44
47
  "lib/prefab/errors/missing_default_error.rb",
45
48
  "lib/prefab/feature_flag_client.rb",
46
49
  "lib/prefab/internal_logger.rb",
50
+ "lib/prefab/local_config_parser.rb",
51
+ "lib/prefab/log_path_collector.rb",
47
52
  "lib/prefab/logger_client.rb",
48
53
  "lib/prefab/murmer3.rb",
49
54
  "lib/prefab/noop_cache.rb",
@@ -51,20 +56,29 @@ Gem::Specification.new do |s|
51
56
  "lib/prefab/options.rb",
52
57
  "lib/prefab/ratelimit_client.rb",
53
58
  "lib/prefab/sse_logger.rb",
59
+ "lib/prefab/weighted_value_resolver.rb",
60
+ "lib/prefab/yaml_config_parser.rb",
54
61
  "lib/prefab_pb.rb",
55
62
  "lib/prefab_services_pb.rb",
56
63
  "prefab-cloud-ruby.gemspec",
57
- "run_test_harness_server.sh",
58
64
  "test/.prefab.default.config.yaml",
59
65
  "test/.prefab.unit_tests.config.yaml",
60
- "test/harness_server.rb",
66
+ "test/integration_test.rb",
67
+ "test/integration_test_helpers.rb",
61
68
  "test/test_client.rb",
62
69
  "test/test_config_client.rb",
63
70
  "test/test_config_loader.rb",
64
71
  "test/test_config_resolver.rb",
72
+ "test/test_config_value_unwrapper.rb",
73
+ "test/test_criteria_evaluator.rb",
65
74
  "test/test_feature_flag_client.rb",
66
75
  "test/test_helper.rb",
67
- "test/test_logger.rb"
76
+ "test/test_integration.rb",
77
+ "test/test_local_config_parser.rb",
78
+ "test/test_log_path_collector.rb",
79
+ "test/test_logger.rb",
80
+ "test/test_options.rb",
81
+ "test/test_weighted_value_resolver.rb"
68
82
  ]
69
83
  s.homepage = "http://github.com/prefab-cloud/prefab-cloud-ruby".freeze
70
84
  s.licenses = ["MIT".freeze]
@@ -78,31 +92,31 @@ Gem::Specification.new do |s|
78
92
  if s.respond_to? :add_runtime_dependency then
79
93
  s.add_runtime_dependency(%q<concurrent-ruby>.freeze, ["~> 1.0", ">= 1.0.5"])
80
94
  s.add_runtime_dependency(%q<faraday>.freeze, [">= 0"])
81
- s.add_runtime_dependency(%q<ld-eventsource>.freeze, [">= 0"])
82
- s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
83
- s.add_runtime_dependency(%q<google-protobuf>.freeze, [">= 0"])
84
95
  s.add_runtime_dependency(%q<googleapis-common-protos-types>.freeze, [">= 0"])
96
+ s.add_runtime_dependency(%q<google-protobuf>.freeze, [">= 0"])
97
+ s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
98
+ s.add_runtime_dependency(%q<ld-eventsource>.freeze, [">= 0"])
99
+ s.add_runtime_dependency(%q<uuid>.freeze, [">= 0"])
85
100
  s.add_development_dependency(%q<benchmark-ips>.freeze, [">= 0"])
86
- s.add_development_dependency(%q<grpc-tools>.freeze, [">= 0"])
87
- s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
88
101
  s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
102
+ s.add_development_dependency(%q<grpc-tools>.freeze, [">= 0"])
89
103
  s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
104
+ s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
90
105
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
91
- s.add_development_dependency(%q<thin>.freeze, [">= 0"])
92
106
  else
93
107
  s.add_dependency(%q<concurrent-ruby>.freeze, ["~> 1.0", ">= 1.0.5"])
94
108
  s.add_dependency(%q<faraday>.freeze, [">= 0"])
95
- s.add_dependency(%q<ld-eventsource>.freeze, [">= 0"])
96
- s.add_dependency(%q<grpc>.freeze, [">= 0"])
97
- s.add_dependency(%q<google-protobuf>.freeze, [">= 0"])
98
109
  s.add_dependency(%q<googleapis-common-protos-types>.freeze, [">= 0"])
110
+ s.add_dependency(%q<google-protobuf>.freeze, [">= 0"])
111
+ s.add_dependency(%q<grpc>.freeze, [">= 0"])
112
+ s.add_dependency(%q<ld-eventsource>.freeze, [">= 0"])
113
+ s.add_dependency(%q<uuid>.freeze, [">= 0"])
99
114
  s.add_dependency(%q<benchmark-ips>.freeze, [">= 0"])
100
- s.add_dependency(%q<grpc-tools>.freeze, [">= 0"])
101
- s.add_dependency(%q<rdoc>.freeze, [">= 0"])
102
115
  s.add_dependency(%q<bundler>.freeze, [">= 0"])
116
+ s.add_dependency(%q<grpc-tools>.freeze, [">= 0"])
103
117
  s.add_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
118
+ s.add_dependency(%q<rdoc>.freeze, [">= 0"])
104
119
  s.add_dependency(%q<simplecov>.freeze, [">= 0"])
105
- s.add_dependency(%q<thin>.freeze, [">= 0"])
106
120
  end
107
121
  end
108
122
 
@@ -9,8 +9,9 @@ sample: test sample value
9
9
  enabled_flag: true
10
10
  disabled_flag: false
11
11
  flag_with_a_value: { "feature_flag": "true", value: "all-features" }
12
- in_lookup_key: { "feature_flag": "true", value: true, criteria: { operator: LOOKUP_KEY_IN, values: [ "abc123", "xyz987" ] } }
13
- just_my_domain: { "feature_flag": "true", value: "new-version", criteria: { operator: PROP_IS_ONE_OF, property: "domain", values: [ "prefab.cloud", "example.com" ] } }
12
+ in_lookup_key: { "feature_flag": "true", value: true, criterion: { operator: LOOKUP_KEY_IN, values: [ "abc123", "xyz987" ] } }
13
+ just_my_domain: { "feature_flag": "true", value: "new-version", criterion: { operator: PROP_IS_ONE_OF, property: "domain", values: [ "prefab.cloud", "example.com" ] } }
14
+
14
15
  nested:
15
16
  values:
16
17
  _: top level