prefab-cloud-ruby 0.2.0 → 0.6.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.
- checksums.yaml +4 -4
- data/.envrc +2 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +47 -56
- data/VERSION +1 -1
- data/lib/prefab-cloud-ruby.rb +2 -1
- data/lib/prefab/auth_interceptor.rb +24 -22
- data/lib/prefab/cancellable_interceptor.rb +47 -0
- data/lib/prefab/client.rb +3 -3
- data/lib/prefab/config_client.rb +28 -12
- data/lib/prefab/config_loader.rb +1 -1
- data/lib/prefab/config_resolver.rb +24 -9
- data/prefab-cloud-ruby.gemspec +8 -6
- data/test/test_config_loader.rb +0 -2
- data/test/test_config_resolver.rb +65 -1
- metadata +12 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa80ee91d95324b503253f95a12deb9b0db91291
|
|
4
|
+
data.tar.gz: 0315d992eb2a87073998e1d7db4864a8c3da289c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e43a7a8dafbfd3a9e6c12cd93b57bed2ee8fd738406fdba166c5eddad03154de66d9150285961f8c08da58d0754fde385b8b68e0bb22f9a27de8441f231a429a
|
|
7
|
+
data.tar.gz: c3586f0e6b689e0ee5b1fd86e621d79ffab5a2263cf977c004fd7a4618cea403059f075f719a86d5a0b4533a16e398e3acb35dff9ca0930082fb81266ef1e545
|
data/.envrc
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,52 +1,42 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: https://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
activesupport (5.2.
|
|
4
|
+
activesupport (5.2.4.5)
|
|
5
5
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
6
6
|
i18n (>= 0.7, < 2)
|
|
7
7
|
minitest (~> 5.1)
|
|
8
8
|
tzinfo (~> 1.1)
|
|
9
|
-
addressable (2.
|
|
10
|
-
public_suffix (>= 2.0.2, <
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
aws-partitions (~> 1.0)
|
|
14
|
-
aws-sigv4 (~> 1.0)
|
|
15
|
-
jmespath (~> 1.0)
|
|
16
|
-
aws-sdk-kms (1.5.0)
|
|
17
|
-
aws-sdk-core (~> 3)
|
|
18
|
-
aws-sigv4 (~> 1.0)
|
|
19
|
-
aws-sdk-s3 (1.10.0)
|
|
20
|
-
aws-sdk-core (~> 3)
|
|
21
|
-
aws-sdk-kms (~> 1)
|
|
22
|
-
aws-sigv4 (~> 1.0)
|
|
23
|
-
aws-sigv4 (1.0.2)
|
|
24
|
-
builder (3.2.3)
|
|
25
|
-
concurrent-ruby (1.0.5)
|
|
9
|
+
addressable (2.7.0)
|
|
10
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
11
|
+
builder (3.2.4)
|
|
12
|
+
concurrent-ruby (1.1.8)
|
|
26
13
|
descendants_tracker (0.0.4)
|
|
27
14
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
28
|
-
docile (1.3.
|
|
29
|
-
faraday (
|
|
15
|
+
docile (1.3.5)
|
|
16
|
+
faraday (1.3.0)
|
|
17
|
+
faraday-net_http (~> 1.0)
|
|
30
18
|
multipart-post (>= 1.2, < 3)
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
ruby2_keywords
|
|
20
|
+
faraday-net_http (1.0.1)
|
|
21
|
+
git (1.8.1)
|
|
22
|
+
rchardet (~> 1.8)
|
|
23
|
+
github_api (0.19.0)
|
|
33
24
|
addressable (~> 2.4)
|
|
34
25
|
descendants_tracker (~> 0.0.4)
|
|
35
|
-
faraday (
|
|
26
|
+
faraday (>= 0.8, < 2)
|
|
36
27
|
hashie (~> 3.5, >= 3.5.2)
|
|
37
28
|
oauth2 (~> 1.0)
|
|
38
|
-
google-protobuf (3.6
|
|
39
|
-
googleapis-common-protos-types (1.0.
|
|
40
|
-
google-protobuf (~> 3.
|
|
41
|
-
grpc (1.
|
|
42
|
-
google-protobuf (~> 3.
|
|
43
|
-
googleapis-common-protos-types (~> 1.0
|
|
29
|
+
google-protobuf (3.15.6)
|
|
30
|
+
googleapis-common-protos-types (1.0.6)
|
|
31
|
+
google-protobuf (~> 3.14)
|
|
32
|
+
grpc (1.36.0)
|
|
33
|
+
google-protobuf (~> 3.14)
|
|
34
|
+
googleapis-common-protos-types (~> 1.0)
|
|
44
35
|
grpc-tools (1.17.1)
|
|
45
36
|
hashie (3.6.0)
|
|
46
|
-
highline (2.0.
|
|
47
|
-
i18n (1.
|
|
37
|
+
highline (2.0.3)
|
|
38
|
+
i18n (1.8.9)
|
|
48
39
|
concurrent-ruby (~> 1.0)
|
|
49
|
-
jmespath (1.4.0)
|
|
50
40
|
json (1.8.6)
|
|
51
41
|
juwelier (2.4.9)
|
|
52
42
|
builder
|
|
@@ -60,52 +50,53 @@ GEM
|
|
|
60
50
|
rake
|
|
61
51
|
rdoc
|
|
62
52
|
semver2
|
|
63
|
-
jwt (2.
|
|
53
|
+
jwt (2.2.2)
|
|
64
54
|
kamelcase (0.0.2)
|
|
65
55
|
semver2 (~> 3)
|
|
66
56
|
mini_portile2 (2.4.0)
|
|
67
|
-
minitest (5.
|
|
68
|
-
multi_json (1.
|
|
57
|
+
minitest (5.14.4)
|
|
58
|
+
multi_json (1.15.0)
|
|
69
59
|
multi_xml (0.6.0)
|
|
70
|
-
multipart-post (2.
|
|
71
|
-
nokogiri (1.10.
|
|
60
|
+
multipart-post (2.1.1)
|
|
61
|
+
nokogiri (1.10.10)
|
|
72
62
|
mini_portile2 (~> 2.4.0)
|
|
73
|
-
oauth2 (1.4.
|
|
74
|
-
faraday (>= 0.8, <
|
|
63
|
+
oauth2 (1.4.7)
|
|
64
|
+
faraday (>= 0.8, < 2.0)
|
|
75
65
|
jwt (>= 1.0, < 3.0)
|
|
76
66
|
multi_json (~> 1.3)
|
|
77
67
|
multi_xml (~> 0.5)
|
|
78
68
|
rack (>= 1.2, < 3)
|
|
79
|
-
psych (3.1
|
|
80
|
-
public_suffix (
|
|
81
|
-
rack (2.
|
|
82
|
-
rake (
|
|
69
|
+
psych (3.3.1)
|
|
70
|
+
public_suffix (4.0.6)
|
|
71
|
+
rack (2.2.3)
|
|
72
|
+
rake (13.0.3)
|
|
73
|
+
rchardet (1.8.0)
|
|
83
74
|
rdoc (3.12.2)
|
|
84
75
|
json (~> 1.4)
|
|
76
|
+
ruby2_keywords (0.0.4)
|
|
85
77
|
semver2 (3.4.2)
|
|
86
|
-
shoulda (
|
|
87
|
-
shoulda-context (~>
|
|
88
|
-
shoulda-matchers (
|
|
89
|
-
shoulda-context (
|
|
90
|
-
shoulda-matchers (
|
|
91
|
-
activesupport (>=
|
|
92
|
-
simplecov (0.
|
|
78
|
+
shoulda (4.0.0)
|
|
79
|
+
shoulda-context (~> 2.0)
|
|
80
|
+
shoulda-matchers (~> 4.0)
|
|
81
|
+
shoulda-context (2.0.0)
|
|
82
|
+
shoulda-matchers (4.5.1)
|
|
83
|
+
activesupport (>= 4.2.0)
|
|
84
|
+
simplecov (0.18.5)
|
|
93
85
|
docile (~> 1.1)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
simplecov-html (0.10.2)
|
|
86
|
+
simplecov-html (~> 0.11)
|
|
87
|
+
simplecov-html (0.12.3)
|
|
97
88
|
thread_safe (0.3.6)
|
|
98
|
-
tzinfo (1.2.
|
|
89
|
+
tzinfo (1.2.9)
|
|
99
90
|
thread_safe (~> 0.1)
|
|
100
91
|
|
|
101
92
|
PLATFORMS
|
|
102
93
|
ruby
|
|
103
94
|
|
|
104
95
|
DEPENDENCIES
|
|
105
|
-
aws-sdk-s3 (~> 1)
|
|
106
96
|
bundler (~> 1.0)
|
|
107
97
|
concurrent-ruby (~> 1.0, >= 1.0.5)
|
|
108
|
-
|
|
98
|
+
faraday
|
|
99
|
+
grpc
|
|
109
100
|
grpc-tools (~> 1.17.1)
|
|
110
101
|
juwelier (~> 2.4.9)
|
|
111
102
|
rdoc (~> 3.12)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.6.0
|
data/lib/prefab-cloud-ruby.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "concurrent/atomics"
|
|
2
2
|
require 'concurrent'
|
|
3
|
+
require 'faraday'
|
|
3
4
|
require 'openssl'
|
|
4
5
|
require 'prefab_pb'
|
|
5
6
|
require 'prefab_services_pb'
|
|
@@ -11,7 +12,7 @@ require 'prefab/config_client'
|
|
|
11
12
|
require 'prefab/feature_flag_client'
|
|
12
13
|
require 'prefab/logger_client'
|
|
13
14
|
require 'prefab/auth_interceptor'
|
|
15
|
+
require 'prefab/cancellable_interceptor'
|
|
14
16
|
require 'prefab/noop_cache'
|
|
15
17
|
require 'prefab/noop_stats'
|
|
16
18
|
require 'prefab/murmer3'
|
|
17
|
-
require 'aws-sdk-s3'
|
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
module Prefab
|
|
2
|
+
class AuthInterceptor < GRPC::ClientInterceptor
|
|
3
|
+
def initialize(api_key)
|
|
4
|
+
version = File.exist?('VERSION') ? File.read('VERSION').chomp : ""
|
|
5
|
+
@client = "prefab-cloud-ruby.#{version}".freeze
|
|
6
|
+
@api_key = api_key
|
|
7
|
+
end
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
def request_response(request:, call:, method:, metadata:, &block)
|
|
10
|
+
shared(metadata, &block)
|
|
11
|
+
end
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
def client_streamer(requests:, call:, method:, metadata:, &block)
|
|
14
|
+
shared(metadata, &block)
|
|
15
|
+
end
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
def server_streamer(request:, call:, method:, metadata:, &block)
|
|
18
|
+
shared(metadata, &block)
|
|
19
|
+
end
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def bidi_streamer(requests:, call:, method:, metadata:, &block)
|
|
22
|
+
shared(metadata, &block)
|
|
23
|
+
end
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
def shared(metadata)
|
|
26
|
+
metadata['auth'] = @api_key
|
|
27
|
+
metadata['client'] = @client
|
|
28
|
+
yield
|
|
29
|
+
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Prefab
|
|
2
|
+
class CancellableInterceptor < GRPC::ClientInterceptor
|
|
3
|
+
WAIT_SEC = 3
|
|
4
|
+
|
|
5
|
+
def initialize(base_client)
|
|
6
|
+
@base_client = base_client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def cancel
|
|
10
|
+
@call.instance_variable_get("@wrapped").instance_variable_get("@call").cancel
|
|
11
|
+
i = 0
|
|
12
|
+
while (i < WAIT_SEC) do
|
|
13
|
+
if @call.instance_variable_get("@wrapped").cancelled?
|
|
14
|
+
@base_client.log_internal Logger::DEBUG, "Cancelled streaming."
|
|
15
|
+
return
|
|
16
|
+
else
|
|
17
|
+
@base_client.log_internal Logger::DEBUG, "Unable to cancel streaming. Trying again"
|
|
18
|
+
@call.instance_variable_get("@wrapped").instance_variable_get("@call").cancel
|
|
19
|
+
i += 1
|
|
20
|
+
sleep(1)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
@base_client.log_internal Logger::INFO, "Unable to cancel streaming."
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def request_response(request:, call:, method:, metadata:, &block)
|
|
27
|
+
shared(call, &block)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def client_streamer(requests:, call:, method:, metadata:, &block)
|
|
31
|
+
shared(call, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def server_streamer(request:, call:, method:, metadata:, &block)
|
|
35
|
+
shared(call, &block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def bidi_streamer(requests:, call:, method:, metadata:, &block)
|
|
39
|
+
shared(call, &block)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def shared(call)
|
|
43
|
+
@call = call
|
|
44
|
+
yield
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/prefab/client.rb
CHANGED
|
@@ -27,7 +27,7 @@ module Prefab
|
|
|
27
27
|
@api_key = api_key
|
|
28
28
|
@account_id = api_key.split("|")[0].to_i
|
|
29
29
|
@namespace = namespace
|
|
30
|
-
@interceptor = AuthInterceptor.new(api_key)
|
|
30
|
+
@interceptor = Prefab::AuthInterceptor.new(api_key)
|
|
31
31
|
@stubs = {}
|
|
32
32
|
|
|
33
33
|
at_exit do
|
|
@@ -91,13 +91,13 @@ module Prefab
|
|
|
91
91
|
"prefab:#{account_id}:#{post_fix}"
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
private
|
|
95
|
-
|
|
96
94
|
def reset!
|
|
97
95
|
@stubs.clear
|
|
98
96
|
@_channel = nil
|
|
99
97
|
end
|
|
100
98
|
|
|
99
|
+
private
|
|
100
|
+
|
|
101
101
|
def stub_for(service, timeout)
|
|
102
102
|
@stubs["#{service}_#{timeout}"] ||= service::Stub.new(nil,
|
|
103
103
|
nil,
|
data/lib/prefab/config_client.rb
CHANGED
|
@@ -2,6 +2,7 @@ module Prefab
|
|
|
2
2
|
class ConfigClient
|
|
3
3
|
RECONNECT_WAIT = 5
|
|
4
4
|
DEFAULT_CHECKPOINT_FREQ_SEC = 60
|
|
5
|
+
DEFAULT_S3CF_BUCKET = 'http://d2j4ed6ti5snnd.cloudfront.net'
|
|
5
6
|
|
|
6
7
|
def initialize(base_client, timeout)
|
|
7
8
|
@base_client = base_client
|
|
@@ -14,13 +15,16 @@ module Prefab
|
|
|
14
15
|
@config_resolver = Prefab::ConfigResolver.new(@base_client, @config_loader)
|
|
15
16
|
|
|
16
17
|
@initialization_lock.acquire_write_lock
|
|
17
|
-
@s3 = Aws::S3::Resource.new(region: 'us-east-1')
|
|
18
18
|
|
|
19
|
+
@cancellable_interceptor = Prefab::CancellableInterceptor.new(@base_client)
|
|
20
|
+
|
|
21
|
+
@s3_cloud_front = ENV["PREFAB_S3CF_BUCKET"] || DEFAULT_S3CF_BUCKET
|
|
19
22
|
load_checkpoint
|
|
20
23
|
start_checkpointing_thread
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def start_streaming
|
|
27
|
+
@streaming = true
|
|
24
28
|
start_api_connection_thread(@config_loader.highwater_mark)
|
|
25
29
|
end
|
|
26
30
|
|
|
@@ -64,13 +68,12 @@ module Prefab
|
|
|
64
68
|
@_stub = Prefab::ConfigService::Stub.new(nil,
|
|
65
69
|
nil,
|
|
66
70
|
channel_override: @base_client.channel,
|
|
67
|
-
interceptors: [@base_client.interceptor])
|
|
71
|
+
interceptors: [@base_client.interceptor, @cancellable_interceptor])
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
# Bootstrap out of the cache
|
|
71
75
|
# returns the high-watermark of what was in the cache
|
|
72
76
|
def load_checkpoint
|
|
73
|
-
|
|
74
77
|
success = load_checkpoint_from_config
|
|
75
78
|
|
|
76
79
|
if !success
|
|
@@ -99,11 +102,14 @@ module Prefab
|
|
|
99
102
|
end
|
|
100
103
|
|
|
101
104
|
def load_checkpoint_from_s3
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
url = "#{@s3_cloud_front}/#{@base_client.api_key.gsub("|", "/")}"
|
|
106
|
+
resp = Faraday.get url
|
|
107
|
+
if resp.status == 200
|
|
108
|
+
deltas = Prefab::ConfigDeltas.decode(resp.body)
|
|
109
|
+
load_deltas(deltas, :s3)
|
|
110
|
+
else
|
|
111
|
+
@base_client.log_internal Logger::INFO, "No S3 checkpoint. Response #{resp.status} Plan may not support this."
|
|
112
|
+
end
|
|
107
113
|
end
|
|
108
114
|
|
|
109
115
|
|
|
@@ -151,8 +157,14 @@ module Prefab
|
|
|
151
157
|
start_at_id: start_at_id)
|
|
152
158
|
@base_client.log_internal Logger::DEBUG, "start api connection thread #{start_at_id}"
|
|
153
159
|
@base_client.stats.increment("prefab.config.api.start")
|
|
160
|
+
|
|
154
161
|
@api_connection_thread = Thread.new do
|
|
155
|
-
|
|
162
|
+
at_exit do
|
|
163
|
+
@streaming = false
|
|
164
|
+
@cancellable_interceptor.cancel
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
while @streaming do
|
|
156
168
|
begin
|
|
157
169
|
resp = stub.get_config(config_req)
|
|
158
170
|
resp.each do |r|
|
|
@@ -163,12 +175,16 @@ module Prefab
|
|
|
163
175
|
finish_init!(:streaming)
|
|
164
176
|
end
|
|
165
177
|
rescue => e
|
|
166
|
-
@
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
if @streaming
|
|
179
|
+
level = e.code == 1 ? Logger::DEBUG : Logger::INFO
|
|
180
|
+
@base_client.log_internal level, ("config client encountered #{e.message} pausing #{RECONNECT_WAIT}")
|
|
181
|
+
reset
|
|
182
|
+
sleep(RECONNECT_WAIT)
|
|
183
|
+
end
|
|
169
184
|
end
|
|
170
185
|
end
|
|
171
186
|
end
|
|
187
|
+
|
|
172
188
|
end
|
|
173
189
|
end
|
|
174
190
|
end
|
data/lib/prefab/config_loader.rb
CHANGED
|
@@ -55,7 +55,7 @@ module Prefab
|
|
|
55
55
|
|
|
56
56
|
def load_local_overrides
|
|
57
57
|
override_dir = ENV['PREFAB_CONFIG_OVERRIDE_DIR'] || Dir.home
|
|
58
|
-
load_glob(File.join(override_dir, ".prefab*config
|
|
58
|
+
load_glob(File.join(override_dir, ".prefab*config.yaml"))
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def load_glob(glob)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module Prefab
|
|
2
2
|
class ConfigResolver
|
|
3
|
+
NAMESPACE_DELIMITER = ".".freeze
|
|
4
|
+
NAME_KEY_DELIMITER = ":".freeze
|
|
3
5
|
|
|
4
6
|
def initialize(base_client, config_loader)
|
|
5
7
|
@lock = Concurrent::ReadWriteLock.new
|
|
@@ -14,7 +16,7 @@ module Prefab
|
|
|
14
16
|
@lock.with_read_lock do
|
|
15
17
|
@local_store.each do |k, v|
|
|
16
18
|
value = v[:value]
|
|
17
|
-
str << "|#{k}| |#{value_of(value)}|#{value_of(value).class}\n"
|
|
19
|
+
str << "|#{k}| in #{v[:namespace]} |#{value_of(value)}|#{value_of(value).class}\n"
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
str
|
|
@@ -52,24 +54,37 @@ module Prefab
|
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
|
|
57
|
+
# Should client a.b.c see key in namespace a.b? yes
|
|
58
|
+
# Should client a.b.c see key in namespace a.b.c? yes
|
|
59
|
+
# Should client a.b.c see key in namespace a.b.d? no
|
|
60
|
+
# Should client a.b.c see key in namespace ""? yes
|
|
61
|
+
#
|
|
62
|
+
def starts_with_ns?(key_namespace, client_namespace)
|
|
63
|
+
zipped = key_namespace.split(NAMESPACE_DELIMITER).zip(client_namespace.split(NAMESPACE_DELIMITER))
|
|
64
|
+
zipped.map do |k, c|
|
|
65
|
+
(k.nil? || k.empty?) || c == k
|
|
66
|
+
end.all?
|
|
67
|
+
end
|
|
68
|
+
|
|
55
69
|
def make_local
|
|
56
70
|
store = {}
|
|
57
71
|
@config_loader.calc_config.each do |prop, value|
|
|
58
72
|
property = prop
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
key_namespace = ""
|
|
74
|
+
|
|
75
|
+
split = prop.split(NAME_KEY_DELIMITER)
|
|
61
76
|
|
|
62
77
|
if split.size > 1
|
|
63
|
-
property = split[1..-1].join
|
|
64
|
-
|
|
78
|
+
property = split[1..-1].join(NAME_KEY_DELIMITER)
|
|
79
|
+
key_namespace = split[0]
|
|
65
80
|
end
|
|
66
81
|
|
|
67
|
-
if (
|
|
82
|
+
if starts_with_ns?(key_namespace, @namespace)
|
|
68
83
|
existing = store[property]
|
|
69
84
|
if existing.nil?
|
|
70
|
-
store[property] = { namespace:
|
|
71
|
-
elsif existing[:namespace].split(
|
|
72
|
-
store[property] = { namespace:
|
|
85
|
+
store[property] = { namespace: key_namespace, value: value }
|
|
86
|
+
elsif existing[:namespace].split(NAMESPACE_DELIMITER).size < key_namespace.split(NAMESPACE_DELIMITER).size
|
|
87
|
+
store[property] = { namespace: key_namespace, value: value }
|
|
73
88
|
end
|
|
74
89
|
end
|
|
75
90
|
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.6.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.6.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 = "2021-03-23"
|
|
15
15
|
s.description = "RateLimits & Config as a service".freeze
|
|
16
16
|
s.email = "jdwyer@prefab.cloud".freeze
|
|
17
17
|
s.extra_rdoc_files = [
|
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
"README.md"
|
|
20
20
|
]
|
|
21
21
|
s.files = [
|
|
22
|
+
".envrc",
|
|
22
23
|
".ruby-version",
|
|
23
24
|
"Gemfile",
|
|
24
25
|
"Gemfile.lock",
|
|
@@ -29,6 +30,7 @@ Gem::Specification.new do |s|
|
|
|
29
30
|
"compile_protos.sh",
|
|
30
31
|
"lib/prefab-cloud-ruby.rb",
|
|
31
32
|
"lib/prefab/auth_interceptor.rb",
|
|
33
|
+
"lib/prefab/cancellable_interceptor.rb",
|
|
32
34
|
"lib/prefab/client.rb",
|
|
33
35
|
"lib/prefab/config_client.rb",
|
|
34
36
|
"lib/prefab/config_loader.rb",
|
|
@@ -60,7 +62,7 @@ Gem::Specification.new do |s|
|
|
|
60
62
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
61
63
|
s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 1.0.5", "~> 1.0"])
|
|
62
64
|
s.add_runtime_dependency(%q<faraday>.freeze, [">= 0"])
|
|
63
|
-
s.add_runtime_dependency(%q<grpc>.freeze, ["
|
|
65
|
+
s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
|
|
64
66
|
s.add_development_dependency(%q<grpc-tools>.freeze, ["~> 1.17.1"])
|
|
65
67
|
s.add_development_dependency(%q<shoulda>.freeze, [">= 0"])
|
|
66
68
|
s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
|
@@ -70,7 +72,7 @@ Gem::Specification.new do |s|
|
|
|
70
72
|
else
|
|
71
73
|
s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.0.5", "~> 1.0"])
|
|
72
74
|
s.add_dependency(%q<faraday>.freeze, [">= 0"])
|
|
73
|
-
s.add_dependency(%q<grpc>.freeze, ["
|
|
75
|
+
s.add_dependency(%q<grpc>.freeze, [">= 0"])
|
|
74
76
|
s.add_dependency(%q<grpc-tools>.freeze, ["~> 1.17.1"])
|
|
75
77
|
s.add_dependency(%q<shoulda>.freeze, [">= 0"])
|
|
76
78
|
s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
|
@@ -81,7 +83,7 @@ Gem::Specification.new do |s|
|
|
|
81
83
|
else
|
|
82
84
|
s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.0.5", "~> 1.0"])
|
|
83
85
|
s.add_dependency(%q<faraday>.freeze, [">= 0"])
|
|
84
|
-
s.add_dependency(%q<grpc>.freeze, ["
|
|
86
|
+
s.add_dependency(%q<grpc>.freeze, [">= 0"])
|
|
85
87
|
s.add_dependency(%q<grpc-tools>.freeze, ["~> 1.17.1"])
|
|
86
88
|
s.add_dependency(%q<shoulda>.freeze, [">= 0"])
|
|
87
89
|
s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
data/test/test_config_loader.rb
CHANGED
|
@@ -25,8 +25,6 @@ class TestConfigLoader < Minitest::Test
|
|
|
25
25
|
assert_equal 5, @loader.highwater_mark
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
28
|
def test_keeps_most_recent
|
|
31
29
|
assert_equal 0, @loader.highwater_mark
|
|
32
30
|
@loader.set(Prefab::ConfigDelta.new(id: 1, key: "sample_int", value: Prefab::ConfigValue.new(int: 1)))
|
|
@@ -18,7 +18,6 @@ class TestConfigResolver < Minitest::Test
|
|
|
18
18
|
@resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
|
|
19
19
|
assert_equal "value_none", @resolver.get("key")
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
@resolverA = resolver_for_namespace("projectA", @loader)
|
|
23
22
|
assert_equal "valueA", @resolverA.get("key")
|
|
24
23
|
|
|
@@ -37,6 +36,71 @@ class TestConfigResolver < Minitest::Test
|
|
|
37
36
|
end
|
|
38
37
|
end
|
|
39
38
|
|
|
39
|
+
def test_starts_with_ns
|
|
40
|
+
@loader = MockConfigLoader.new
|
|
41
|
+
@loader.stub :calc_config, {} do
|
|
42
|
+
resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
|
|
43
|
+
assert resolver.send(:starts_with_ns?, "", "a")
|
|
44
|
+
assert resolver.send(:starts_with_ns?, "a", "a")
|
|
45
|
+
assert resolver.send(:starts_with_ns?, "a", "a.b")
|
|
46
|
+
assert !resolver.send(:starts_with_ns?, "a.b", "a")
|
|
47
|
+
|
|
48
|
+
assert resolver.send(:starts_with_ns?, "corp", "corp.proj.proja")
|
|
49
|
+
assert resolver.send(:starts_with_ns?, "corp.proj", "corp.proj.proja")
|
|
50
|
+
assert resolver.send(:starts_with_ns?, "corp.proj.proja", "corp.proj.proja")
|
|
51
|
+
assert !resolver.send(:starts_with_ns?, "corp.proj.projb", "corp.proj.proja")
|
|
52
|
+
|
|
53
|
+
# corp:a:b is not a real delimited namespace
|
|
54
|
+
assert !resolver.send(:starts_with_ns?, "corp", "corp:a:b")
|
|
55
|
+
assert resolver.send(:starts_with_ns?, "foo", "foo.baz")
|
|
56
|
+
assert resolver.send(:starts_with_ns?, "foo.baz", "foo.baz")
|
|
57
|
+
assert !resolver.send(:starts_with_ns?, "foo.baz", "foo.bazz")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# colons are not allowed in keys, but verify behavior anyway
|
|
62
|
+
def test_keys_with_colons
|
|
63
|
+
@loader = MockConfigLoader.new
|
|
64
|
+
loaded_values = {
|
|
65
|
+
"Key:With:Colons" => Prefab::ConfigValue.new(string: "value"),
|
|
66
|
+
"proj:apikey" => Prefab::ConfigValue.new(string: "v2")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@loader.stub :calc_config, loaded_values do
|
|
70
|
+
|
|
71
|
+
r = resolver_for_namespace("foo", @loader)
|
|
72
|
+
assert_nil r.get("apikey")
|
|
73
|
+
|
|
74
|
+
r = resolver_for_namespace("proj", @loader)
|
|
75
|
+
assert_equal "v2", r.get("apikey")
|
|
76
|
+
|
|
77
|
+
r = resolver_for_namespace("", @loader)
|
|
78
|
+
assert_nil r.get("apikey")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@resolverKeyWith = resolver_for_namespace("Ket:With", @loader)
|
|
82
|
+
assert_nil @resolverKeyWith.get("Colons")
|
|
83
|
+
assert_nil @resolverKeyWith.get("With:Colons")
|
|
84
|
+
assert_nil @resolverKeyWith.get("Key:With:Colons")
|
|
85
|
+
|
|
86
|
+
@resolverKeyWithExtra = resolver_for_namespace("Key:With:Extra", @loader)
|
|
87
|
+
puts @resolverKeyWithExtra.to_s
|
|
88
|
+
assert_nil @resolverKeyWithExtra.get("Colons")
|
|
89
|
+
assert_nil @resolverKeyWithExtra.get("With:Colons")
|
|
90
|
+
assert_nil @resolverKeyWithExtra.get("Key:With:Colons")
|
|
91
|
+
|
|
92
|
+
@resolverKey = resolver_for_namespace("Key", @loader)
|
|
93
|
+
assert_equal "value", @resolverKey.get("With:Colons")
|
|
94
|
+
assert_nil @resolverKey.get("Colons")
|
|
95
|
+
assert_nil @resolverKey.get("Key:With:Colons")
|
|
96
|
+
|
|
97
|
+
@resolverWithProperlySegmentedNamespace = resolver_for_namespace("Key.With.Extra", @loader)
|
|
98
|
+
assert_nil @resolverWithProperlySegmentedNamespace.get("Colons")
|
|
99
|
+
assert_equal "value", @resolverWithProperlySegmentedNamespace.get("With:Colons")
|
|
100
|
+
assert_nil @resolverWithProperlySegmentedNamespace.get("Key:With:Colons")
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
40
104
|
def resolver_for_namespace(namespace, loader)
|
|
41
105
|
Prefab::ConfigResolver.new(MockBaseClient.new(namespace: namespace), loader)
|
|
42
106
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prefab-cloud-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeff Dwyer
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-03-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -48,16 +48,16 @@ dependencies:
|
|
|
48
48
|
name: grpc
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
|
-
- - "
|
|
51
|
+
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
53
|
+
version: '0'
|
|
54
54
|
type: :runtime
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
|
-
- - "
|
|
58
|
+
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
60
|
+
version: '0'
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: grpc-tools
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,6 +150,7 @@ extra_rdoc_files:
|
|
|
150
150
|
- LICENSE.txt
|
|
151
151
|
- README.md
|
|
152
152
|
files:
|
|
153
|
+
- ".envrc"
|
|
153
154
|
- ".ruby-version"
|
|
154
155
|
- Gemfile
|
|
155
156
|
- Gemfile.lock
|
|
@@ -160,6 +161,7 @@ files:
|
|
|
160
161
|
- compile_protos.sh
|
|
161
162
|
- lib/prefab-cloud-ruby.rb
|
|
162
163
|
- lib/prefab/auth_interceptor.rb
|
|
164
|
+
- lib/prefab/cancellable_interceptor.rb
|
|
163
165
|
- lib/prefab/client.rb
|
|
164
166
|
- lib/prefab/config_client.rb
|
|
165
167
|
- lib/prefab/config_loader.rb
|
|
@@ -183,7 +185,7 @@ homepage: http://github.com/prefab-cloud/prefab-cloud-ruby
|
|
|
183
185
|
licenses:
|
|
184
186
|
- MIT
|
|
185
187
|
metadata: {}
|
|
186
|
-
post_install_message:
|
|
188
|
+
post_install_message:
|
|
187
189
|
rdoc_options: []
|
|
188
190
|
require_paths:
|
|
189
191
|
- lib
|
|
@@ -198,9 +200,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
198
200
|
- !ruby/object:Gem::Version
|
|
199
201
|
version: '0'
|
|
200
202
|
requirements: []
|
|
201
|
-
rubyforge_project:
|
|
203
|
+
rubyforge_project:
|
|
202
204
|
rubygems_version: 2.6.14
|
|
203
|
-
signing_key:
|
|
205
|
+
signing_key:
|
|
204
206
|
specification_version: 4
|
|
205
207
|
summary: Prefab Ruby Infrastructure
|
|
206
208
|
test_files: []
|