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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57dd1f5909bf80cd820396d039c2d1560faf55e6
4
- data.tar.gz: d2e6192bf1126aadc4aaa49e23728cfbaaf2a689
3
+ metadata.gz: fa80ee91d95324b503253f95a12deb9b0db91291
4
+ data.tar.gz: 0315d992eb2a87073998e1d7db4864a8c3da289c
5
5
  SHA512:
6
- metadata.gz: 61ff17aeda32522ed65ace11b48b955f87eeb69cc9ccc781c3dfecca66161469a93a96db42559919f347e4998b3d42038890dd22219e2ec722a01eb61323b6cf
7
- data.tar.gz: 87b2c0a1a2544cd9c7f93fdda3d1e96028424642e5d6fd9dd8fd3c9c334ef5f146d5ba0fe006ebb6fa27ad6e7bee6488d92dedcb2546b516e2dec61e71121509
6
+ metadata.gz: e43a7a8dafbfd3a9e6c12cd93b57bed2ee8fd738406fdba166c5eddad03154de66d9150285961f8c08da58d0754fde385b8b68e0bb22f9a27de8441f231a429a
7
+ data.tar.gz: c3586f0e6b689e0ee5b1fd86e621d79ffab5a2263cf977c004fd7a4618cea403059f075f719a86d5a0b4533a16e398e3acb35dff9ca0930082fb81266ef1e545
data/.envrc ADDED
@@ -0,0 +1,2 @@
1
+ export AWS_ACCESS_KEY_ID=
2
+ export AWS_SECRET_ACCESS_KEY=
data/Gemfile CHANGED
@@ -1,8 +1,8 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'grpc', '~> 1.17.1'
4
3
  gem 'concurrent-ruby', '~> 1.0', '>= 1.0.5'
5
- gem 'aws-sdk-s3', '~> 1'
4
+ gem 'faraday'
5
+ gem 'grpc'
6
6
 
7
7
  group :development do
8
8
  gem 'grpc-tools', '~> 1.17.1'
data/Gemfile.lock CHANGED
@@ -1,52 +1,42 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- activesupport (5.2.0)
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.6.0)
10
- public_suffix (>= 2.0.2, < 4.0)
11
- aws-partitions (1.86.0)
12
- aws-sdk-core (3.20.2)
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.0)
29
- faraday (0.15.4)
15
+ docile (1.3.5)
16
+ faraday (1.3.0)
17
+ faraday-net_http (~> 1.0)
30
18
  multipart-post (>= 1.2, < 3)
31
- git (1.5.0)
32
- github_api (0.18.2)
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 (~> 0.8)
26
+ faraday (>= 0.8, < 2)
36
27
  hashie (~> 3.5, >= 3.5.2)
37
28
  oauth2 (~> 1.0)
38
- google-protobuf (3.6.1)
39
- googleapis-common-protos-types (1.0.2)
40
- google-protobuf (~> 3.0)
41
- grpc (1.17.1)
42
- google-protobuf (~> 3.1)
43
- googleapis-common-protos-types (~> 1.0.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.1)
47
- i18n (1.0.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.1.0)
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.11.3)
68
- multi_json (1.13.1)
57
+ minitest (5.14.4)
58
+ multi_json (1.15.0)
69
59
  multi_xml (0.6.0)
70
- multipart-post (2.0.0)
71
- nokogiri (1.10.1)
60
+ multipart-post (2.1.1)
61
+ nokogiri (1.10.10)
72
62
  mini_portile2 (~> 2.4.0)
73
- oauth2 (1.4.1)
74
- faraday (>= 0.8, < 0.16.0)
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.0)
80
- public_suffix (3.0.3)
81
- rack (2.0.6)
82
- rake (12.3.2)
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 (3.5.0)
87
- shoulda-context (~> 1.0, >= 1.0.1)
88
- shoulda-matchers (>= 1.4.1, < 3.0)
89
- shoulda-context (1.2.2)
90
- shoulda-matchers (2.8.0)
91
- activesupport (>= 3.0.0)
92
- simplecov (0.16.1)
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
- json (>= 1.8, < 3)
95
- simplecov-html (~> 0.10.0)
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.5)
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
- grpc (~> 1.17.1)
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.1
1
+ 0.6.0
@@ -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
- class AuthInterceptor < GRPC::ClientInterceptor
2
- def initialize(api_key)
3
- version = File.exist?('VERSION') ? File.read('VERSION').chomp : ""
4
- @client = "prefab-cloud-ruby.#{version}".freeze
5
- @api_key = api_key
6
- end
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
- def request_response(request:, call:, method:, metadata:, &block)
9
- shared(metadata, &block)
10
- end
9
+ def request_response(request:, call:, method:, metadata:, &block)
10
+ shared(metadata, &block)
11
+ end
11
12
 
12
- def client_streamer(requests:, call:, method:, metadata:, &block)
13
- shared(metadata, &block)
14
- end
13
+ def client_streamer(requests:, call:, method:, metadata:, &block)
14
+ shared(metadata, &block)
15
+ end
15
16
 
16
- def server_streamer(request:, call:, method:, metadata:, &block)
17
- shared(metadata, &block)
18
- end
17
+ def server_streamer(request:, call:, method:, metadata:, &block)
18
+ shared(metadata, &block)
19
+ end
19
20
 
20
- def bidi_streamer(requests:, call:, method:, metadata:, &block)
21
- shared(metadata, &block)
22
- end
21
+ def bidi_streamer(requests:, call:, method:, metadata:, &block)
22
+ shared(metadata, &block)
23
+ end
23
24
 
24
- def shared(metadata)
25
- metadata['auth'] = @api_key
26
- metadata['client'] = @client
27
- yield
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,
@@ -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
- resp = @s3.bucket('prefab-cloud-checkpoints-prod').object(@base_client.api_key.gsub("|", "/")).get
103
- deltas = Prefab::ConfigDeltas.decode(resp.body.read)
104
- load_deltas(deltas, :s3)
105
- rescue Aws::S3::Errors::NoSuchKey
106
- @base_client.log_internal Logger::INFO, "No S3 checkpoint. Plan may not support this."
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
- while true do
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
- @base_client.log_internal Logger::INFO, ("config client encountered #{e.message} pausing #{RECONNECT_WAIT}")
167
- reset
168
- sleep(RECONNECT_WAIT)
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
@@ -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-overrides.yaml"))
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
- namespace = ""
60
- split = prop.split(":")
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
- namespace = split[0]
78
+ property = split[1..-1].join(NAME_KEY_DELIMITER)
79
+ key_namespace = split[0]
65
80
  end
66
81
 
67
- if (namespace == "") || @namespace.start_with?(namespace)
82
+ if starts_with_ns?(key_namespace, @namespace)
68
83
  existing = store[property]
69
84
  if existing.nil?
70
- store[property] = { namespace: namespace, value: value }
71
- elsif existing[:namespace].split(".").size < namespace.split(".").size
72
- store[property] = { namespace: namespace, value: value }
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
@@ -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.2.0 ruby lib
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.2.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 = "2019-01-30"
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, ["~> 1.17.1"])
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, ["~> 1.17.1"])
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, ["~> 1.17.1"])
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"])
@@ -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.2.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: 2019-01-30 00:00:00.000000000 Z
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: 1.17.1
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: 1.17.1
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: []