prefab-cloud-ruby 0.20.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.envrc.sample +3 -0
- data/.github/workflows/ruby.yml +5 -1
- data/.gitmodules +3 -0
- data/Gemfile +14 -12
- data/Gemfile.lock +24 -14
- data/README.md +12 -10
- data/Rakefile +13 -14
- data/VERSION +1 -1
- data/lib/prefab/auth_interceptor.rb +2 -1
- data/lib/prefab/cancellable_interceptor.rb +8 -7
- data/lib/prefab/client.rb +52 -27
- data/lib/prefab/config_client.rb +59 -70
- data/lib/prefab/config_loader.rb +7 -114
- data/lib/prefab/config_resolver.rb +27 -57
- data/lib/prefab/config_value_unwrapper.rb +23 -0
- data/lib/prefab/criteria_evaluator.rb +96 -0
- data/lib/prefab/errors/invalid_api_key_error.rb +1 -1
- data/lib/prefab/feature_flag_client.rb +13 -145
- data/lib/prefab/internal_logger.rb +7 -6
- data/lib/prefab/local_config_parser.rb +110 -0
- data/lib/prefab/log_path_collector.rb +98 -0
- data/lib/prefab/logger_client.rb +46 -44
- data/lib/prefab/murmer3.rb +3 -4
- data/lib/prefab/noop_cache.rb +5 -7
- data/lib/prefab/noop_stats.rb +2 -3
- data/lib/prefab/options.rb +32 -11
- data/lib/prefab/ratelimit_client.rb +11 -13
- data/lib/prefab/sse_logger.rb +3 -2
- data/lib/prefab/weighted_value_resolver.rb +42 -0
- data/lib/prefab/yaml_config_parser.rb +32 -0
- data/lib/prefab-cloud-ruby.rb +7 -2
- data/lib/prefab_pb.rb +70 -43
- data/lib/prefab_services_pb.rb +14 -1
- data/prefab-cloud-ruby.gemspec +33 -19
- data/test/.prefab.unit_tests.config.yaml +3 -2
- data/test/integration_test.rb +98 -0
- data/test/integration_test_helpers.rb +37 -0
- data/test/test_client.rb +56 -31
- data/test/test_config_client.rb +21 -20
- data/test/test_config_loader.rb +48 -37
- data/test/test_config_resolver.rb +312 -135
- data/test/test_config_value_unwrapper.rb +83 -0
- data/test/test_criteria_evaluator.rb +533 -0
- data/test/test_feature_flag_client.rb +35 -347
- data/test/test_helper.rb +18 -14
- data/test/test_integration.rb +33 -0
- data/test/test_local_config_parser.rb +78 -0
- data/test/test_log_path_collector.rb +56 -0
- data/test/test_logger.rb +52 -51
- data/test/test_options.rb +32 -0
- data/test/test_weighted_value_resolver.rb +65 -0
- metadata +30 -16
- data/lib/prefab/config_helper.rb +0 -31
- data/run_test_harness_server.sh +0 -8
- data/test/harness_server.rb +0 -64
data/lib/prefab/options.rb
CHANGED
@@ -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}:#{
|
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
|
-
|
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[
|
47
|
-
prefab_grpc_url: ENV[
|
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'] ==
|
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:
|
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(/\./,
|
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
|
-
|
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(
|
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},
|
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(
|
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(
|
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
|
-
|
data/lib/prefab/sse_logger.rb
CHANGED
@@ -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(
|
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
|
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
|
data/lib/prefab-cloud-ruby.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
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/
|
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 :
|
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, :
|
44
|
+
optional :changed_by, :message, 4, "prefab.ChangedBy"
|
35
45
|
repeated :rows, :message, 5, "prefab.ConfigRow"
|
36
|
-
repeated :
|
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
|
-
|
40
|
-
|
41
|
-
|
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.
|
79
|
-
|
80
|
-
|
81
|
-
|
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.
|
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
|
-
|
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
|
-
|
216
|
-
|
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
|
data/lib/prefab_services_pb.rb
CHANGED
@@ -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
|
data/prefab-cloud-ruby.gemspec
CHANGED
@@ -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.
|
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.
|
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 = "
|
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/
|
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/
|
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,
|
13
|
-
just_my_domain: { "feature_flag": "true", value: "new-version",
|
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
|