prefab-cloud-ruby 0.23.3 → 0.23.4

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
  SHA256:
3
- metadata.gz: 45234586612606d2efe94b569039c7f7866b948b1cc9ef1d252c3af68b678ac0
4
- data.tar.gz: c4ca19037512f306fe4fe62a6031d56153a68d549e58a64e3754050af6b91948
3
+ metadata.gz: 74e19eed1d40cad8e3ea9b99a8755c90864a97b4a00e08d2df6a9fe5226f5ad0
4
+ data.tar.gz: 4ad94565a39139d01795007077128d8f997c05e6a8b785e019ca8b66308df5c5
5
5
  SHA512:
6
- metadata.gz: 1562416434735eb380f3cc7e159120a43e4f18e22f486020cfe7a35dc0c66f2c10a04104e46120c6f455a70ff7078c35ce16978bb1a111669686971be3a9c432
7
- data.tar.gz: 4671527a60e7166e3acbeca47bbe211d405ceda58600c621406cf865b0942864d7b2d7c5f71c8fbb7ccc0e020113cf8921f7dcf5a9fe5b7a81b887392ef35460
6
+ metadata.gz: 7a10679fe049175ebaf01f12194f91bea1a98ce226bf0e0f3e87aea3ab299c888fb7cebfe67b942e77dc46367c9b05cc5acaf995870e1d6ee1f2b8aa744f2fa3
7
+ data.tar.gz: c6e506da285ae5f7913f81891e7f32a1b5365f1071bc90323f317aa2523fddb0bd41c2d8a53decf2afec000e234d535713e198f3ac8b4c98259c7904f03ce7ad
data/Gemfile CHANGED
@@ -4,14 +4,12 @@ gem 'concurrent-ruby', '~> 1.0', '>= 1.0.5'
4
4
  gem 'faraday'
5
5
  gem 'googleapis-common-protos-types', platforms: :ruby
6
6
  gem 'google-protobuf', platforms: :ruby
7
- gem 'grpc', platforms: :ruby
8
7
  gem 'ld-eventsource'
9
8
  gem 'uuid'
10
9
 
11
10
  group :development do
12
11
  gem 'benchmark-ips'
13
12
  gem 'bundler'
14
- gem 'grpc-tools', platforms: :ruby
15
13
  gem 'juwelier', '~> 2.4.9'
16
14
  gem 'rdoc'
17
15
  gem 'simplecov', '>= 0'
data/Gemfile.lock CHANGED
@@ -33,10 +33,6 @@ GEM
33
33
  google-protobuf (3.22.2)
34
34
  googleapis-common-protos-types (1.5.0)
35
35
  google-protobuf (~> 3.14)
36
- grpc (1.53.0)
37
- google-protobuf (~> 3.21)
38
- googleapis-common-protos-types (~> 1.0)
39
- grpc-tools (1.43.1)
40
36
  hashie (3.6.0)
41
37
  highline (2.0.3)
42
38
  http (5.0.1)
@@ -124,8 +120,6 @@ DEPENDENCIES
124
120
  faraday
125
121
  google-protobuf
126
122
  googleapis-common-protos-types
127
- grpc
128
- grpc-tools
129
123
  juwelier (~> 2.4.9)
130
124
  ld-eventsource
131
125
  minitest
data/README.md CHANGED
@@ -28,9 +28,7 @@ See full documentation https://docs.prefab.cloud/docs/ruby-sdk/ruby
28
28
 
29
29
  ## Important note about Forking and realtime updates
30
30
 
31
- Many ruby web servers fork. GRPC does not like to be forked. See some details on GRPC and forking: https://github.com/grpc/grpc/issues/7951#issuecomment-335998583
32
-
33
- If you're using Puma or Unicorn, you can do the following.
31
+ Many ruby web servers fork. When the process is forked, the current realtime update stream is disconnected. If you're using Puma or Unicorn, do the following.
34
32
 
35
33
  ```ruby
36
34
  #config/initializers/prefab.rb
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ Juwelier::Tasks.new do |gem|
17
17
  gem.homepage = 'http://github.com/prefab-cloud/prefab-cloud-ruby'
18
18
  gem.license = 'MIT'
19
19
  gem.summary = %(Prefab Ruby Infrastructure)
20
- gem.description = %(RateLimits & Config as a service)
20
+ gem.description = %(Feature Flags, Live Config, and Dynamic Log Levels as a service)
21
21
  gem.email = 'jdwyer@prefab.cloud'
22
22
  gem.authors = ['Jeff Dwyer']
23
23
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.23.3
1
+ 0.23.4
data/lib/prefab/client.rb CHANGED
@@ -31,14 +31,8 @@ module Prefab
31
31
  @api_key = @options.api_key
32
32
  raise Prefab::Errors::InvalidApiKeyError, @api_key if @api_key.nil? || @api_key.empty? || api_key.count('-') < 1
33
33
 
34
- @interceptor = Prefab::AuthInterceptor.new(@api_key)
35
34
  @prefab_api_url = @options.prefab_api_url
36
- @prefab_grpc_url = @options.prefab_grpc_url
37
- log_internal ::Logger::INFO,
38
- "Prefab Connecting to: #{@prefab_api_url} and #{@prefab_grpc_url} Secure: #{http_secure?}"
39
- at_exit do
40
- channel.destroy
41
- end
35
+ log_internal ::Logger::INFO, "Prefab Connecting to: #{@prefab_api_url}"
42
36
  end
43
37
  # start config client
44
38
  config_client
@@ -54,19 +48,10 @@ module Prefab
54
48
  Thread.current[:prefab_log_properties] = {}
55
49
  end
56
50
 
57
- def channel
58
- credentials = http_secure? ? creds : :this_channel_is_insecure
59
- @_channel ||= GRPC::Core::Channel.new(@prefab_grpc_url, nil, credentials)
60
- end
61
-
62
51
  def config_client(timeout: 5.0)
63
52
  @config_client ||= Prefab::ConfigClient.new(self, timeout)
64
53
  end
65
54
 
66
- def ratelimit_client(timeout: 5.0)
67
- @ratelimit_client ||= Prefab::RateLimitClient.new(self, timeout)
68
- end
69
-
70
55
  def feature_flag_client
71
56
  @feature_flag_client ||= Prefab::FeatureFlagClient.new(self)
72
57
  end
@@ -97,39 +82,6 @@ module Prefab
97
82
  log.log_internal msg, path, nil, level
98
83
  end
99
84
 
100
- def request(service, method, req_options: {}, params: {})
101
- # Future-proofing since we previously bumped into a conflict with a service with a `send` method
102
- raise ArgumentError, 'Cannot call public_send on an grpc service in Ruby' if method.to_s == 'public_send'
103
-
104
- opts = { timeout: 10 }.merge(req_options)
105
-
106
- attempts = 0
107
- start_time = Time.now
108
-
109
- begin
110
- attempts += 1
111
-
112
- stub_for(service, opts[:timeout]).public_send(method, *params)
113
- rescue StandardError => e
114
- log_internal ::Logger::WARN, e
115
-
116
- raise e if Time.now - start_time > opts[:timeout]
117
-
118
- sleep_seconds = [BASE_SLEEP_SEC * (2**(attempts - 1)), MAX_SLEEP_SEC].min
119
- sleep_seconds *= (0.5 * (1 + rand))
120
- sleep_seconds = [BASE_SLEEP_SEC, sleep_seconds].max
121
- log_internal ::Logger::INFO, "Sleep #{sleep_seconds} and Reset #{service} #{method}"
122
- sleep sleep_seconds
123
- reset!
124
- retry
125
- end
126
- end
127
-
128
- def reset!
129
- @stubs.clear
130
- @_channel = nil
131
- end
132
-
133
85
  def enabled?(feature_name, lookup_key = nil, attributes = {})
134
86
  feature_flag_client.feature_is_on_for?(feature_name, lookup_key, attributes: attributes)
135
87
  end
@@ -142,6 +94,10 @@ module Prefab
142
94
  end
143
95
  end
144
96
 
97
+ def post(path, body)
98
+ Prefab::HttpConnection.new(@options.prefab_api_url, @api_key).post(path, body)
99
+ end
100
+
145
101
  private
146
102
 
147
103
  def is_ff?(key)
@@ -149,35 +105,5 @@ module Prefab
149
105
 
150
106
  raw && raw.allowable_values.any?
151
107
  end
152
-
153
- def http_secure?
154
- ENV['PREFAB_CLOUD_HTTP'] != 'true'
155
- end
156
-
157
- def stub_for(service, timeout)
158
- @stubs["#{service}_#{timeout}"] ||= service::Stub.new(nil,
159
- nil,
160
- timeout: timeout,
161
- channel_override: channel,
162
- interceptors: [@interceptor])
163
- end
164
-
165
- def creds
166
- GRPC::Core::ChannelCredentials.new(ssl_certs)
167
- end
168
-
169
- def ssl_certs
170
- ssl_certs = ''
171
- Dir["#{OpenSSL::X509::DEFAULT_CERT_DIR}/*.pem"].each do |cert|
172
- ssl_certs += File.open(cert).read
173
- end
174
- if OpenSSL::X509::DEFAULT_CERT_FILE && File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE)
175
- ssl_certs += File.open(OpenSSL::X509::DEFAULT_CERT_FILE).read
176
- end
177
- ssl_certs
178
- rescue StandardError => e
179
- log.warn("Issue loading SSL certs #{e.message}")
180
- ssl_certs
181
- end
182
108
  end
183
109
  end
@@ -26,8 +26,6 @@ module Prefab
26
26
  @base_client.log_internal ::Logger::DEBUG, 'Initialize ConfigClient: AcquiredWriteLock'
27
27
  @initialized_future = Concurrent::Future.execute { @initialization_lock.acquire_read_lock }
28
28
 
29
- @cancellable_interceptor = Prefab::CancellableInterceptor.new(@base_client)
30
-
31
29
  if @options.local_only?
32
30
  finish_init!(:local_only)
33
31
  else
@@ -58,11 +56,6 @@ module Prefab
58
56
  @config_resolver.update
59
57
  end
60
58
 
61
- def reset
62
- @base_client.reset!
63
- @_stub = nil
64
- end
65
-
66
59
  def to_s
67
60
  @config_resolver.to_s
68
61
  end
@@ -108,54 +101,28 @@ module Prefab
108
101
  @config_resolver.get(key, lookup_key, properties)
109
102
  end
110
103
 
111
- def stub
112
- @_stub = Prefab::ConfigService::Stub.new(nil,
113
- nil,
114
- channel_override: @base_client.channel,
115
- interceptors: [@base_client.interceptor, @cancellable_interceptor])
116
- end
117
-
118
104
  def load_checkpoint
119
105
  success = load_checkpoint_api_cdn
120
106
 
121
107
  return if success
122
108
 
123
- @base_client.log_internal ::Logger::INFO, 'LoadCheckpoint: Fallback to GRPC API'
124
-
125
- success = load_checkpoint_from_grpc_api
109
+ success = load_checkpoint_api
126
110
 
127
111
  return if success
128
112
 
129
113
  @base_client.log_internal ::Logger::WARN, 'No success loading checkpoints'
130
114
  end
131
115
 
132
- def load_checkpoint_from_grpc_api
133
- config_req = Prefab::ConfigServicePointer.new(start_at_id: @config_loader.highwater_mark)
134
-
135
- resp = stub.get_all_config(config_req)
136
- load_configs(resp, :remote_api_grpc)
137
- true
138
- rescue GRPC::Unauthenticated
139
- @base_client.log_internal ::Logger::WARN, 'Unauthenticated'
140
- rescue StandardError => e
141
- @base_client.log_internal ::Logger::WARN, "Unexpected grpc_api problem loading checkpoint #{e}"
142
- false
143
- end
144
-
145
116
  def load_checkpoint_api_cdn
146
- url = "#{@options.url_for_api_cdn}/api/v1/configs/0"
147
- conn = if Faraday::VERSION[0].to_i >= 2
148
- Faraday.new(url) do |conn|
149
- conn.request :authorization, :basic, AUTH_USER, @base_client.api_key
150
- end
151
- else
152
- Faraday.new(url) do |conn|
153
- conn.request :basic_auth, AUTH_USER, @base_client.api_key
154
- end
155
- end
117
+ conn = Prefab::HttpConnection.new("#{@options.url_for_api_cdn}/api/v1/configs/0", @base_client.api_key)
156
118
  load_url(conn, :remote_cdn_api)
157
119
  end
158
120
 
121
+ def load_checkpoint_api
122
+ conn = Prefab::HttpConnection.new("#{@options.prefab_api_url}/api/v1/configs/0", @base_client.api_key)
123
+ load_url(conn, :remote_api)
124
+ end
125
+
159
126
  def load_url(conn, source)
160
127
  resp = conn.get('')
161
128
  if resp.status == 200
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prefab
4
+ class HttpConnection
5
+ AUTH_USER = 'authuser'
6
+ PROTO_HEADERS = { 'Content-Type' => 'application/x-protobuf', 'Accept' => 'application/x-protobuf' }.freeze
7
+
8
+ def initialize(api_root, api_key)
9
+ @api_root = api_root
10
+ @api_key = api_key
11
+ end
12
+
13
+ def get(path)
14
+ connection.get(path)
15
+ end
16
+
17
+ def post(path, body)
18
+ connection(PROTO_HEADERS).post(path, body.to_proto)
19
+ end
20
+
21
+ def connection(headers = {})
22
+ if Faraday::VERSION[0].to_i >= 2
23
+ Faraday.new(@api_root) do |conn|
24
+ conn.request :authorization, :basic, AUTH_USER, @api_key
25
+
26
+ conn.headers.merge!(headers)
27
+ end
28
+ else
29
+ Faraday.new(@api_root) do |conn|
30
+ conn.request :basic_auth, AUTH_USER, @api_key
31
+
32
+ conn.headers.merge!(headers)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -76,7 +76,7 @@ module Prefab
76
76
  namespace: @client.namespace
77
77
  )
78
78
 
79
- @client.request Prefab::LoggerReportingService, :send, req_options: {}, params: loggers
79
+ @client.post('/api/v1/known-loggers', loggers)
80
80
  end
81
81
  end
82
82
 
@@ -10,7 +10,6 @@ module Prefab
10
10
  attr_reader :shared_cache
11
11
  attr_reader :namespace
12
12
  attr_reader :prefab_api_url
13
- attr_reader :prefab_grpc_url
14
13
  attr_reader :on_no_default
15
14
  attr_reader :initialization_timeout_sec
16
15
  attr_reader :on_init_failure
@@ -49,7 +48,6 @@ module Prefab
49
48
  log_formatter: DEFAULT_LOG_FORMATTER,
50
49
  log_prefix: nil,
51
50
  prefab_api_url: ENV['PREFAB_API_URL'] || 'https://api.prefab.cloud',
52
- prefab_grpc_url: ENV['PREFAB_GRPC_URL'] || 'grpc.prefab.cloud:443',
53
51
  on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
54
52
  initialization_timeout_sec: 10, # how long to wait before on_init_failure
55
53
  on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, # options :unlock_and_continue, :lock_and_keep_trying, :raise
@@ -71,7 +69,6 @@ module Prefab
71
69
  @log_formatter = log_formatter
72
70
  @log_prefix = log_prefix
73
71
  @prefab_api_url = remove_trailing_slash(prefab_api_url)
74
- @prefab_grpc_url = prefab_grpc_url
75
72
  @on_no_default = on_no_default
76
73
  @initialization_timeout_sec = initialization_timeout_sec
77
74
  @on_init_failure = on_init_failure
@@ -12,7 +12,6 @@ require 'prefab/exponential_backoff'
12
12
  require 'prefab/errors/initialization_timeout_error'
13
13
  require 'prefab/errors/invalid_api_key_error'
14
14
  require 'prefab/errors/missing_default_error'
15
- require 'prefab_services_pb'
16
15
  require 'prefab/options'
17
16
  require 'prefab/internal_logger'
18
17
  require 'prefab/sse_logger'
@@ -23,13 +22,11 @@ require 'prefab/config_loader'
23
22
  require 'prefab/local_config_parser'
24
23
  require 'prefab/yaml_config_parser'
25
24
  require 'prefab/config_resolver'
25
+ require 'prefab/http_connection'
26
26
  require 'prefab/client'
27
- require 'prefab/ratelimit_client'
28
27
  require 'prefab/config_client'
29
28
  require 'prefab/feature_flag_client'
30
29
  require 'prefab/logger_client'
31
- require 'prefab/auth_interceptor'
32
- require 'prefab/cancellable_interceptor'
33
30
  require 'prefab/noop_cache'
34
31
  require 'prefab/noop_stats'
35
32
  require 'prefab/murmer3'
@@ -2,17 +2,17 @@
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.23.3 ruby lib
5
+ # stub: prefab-cloud-ruby 0.23.4 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.23.3"
9
+ s.version = "0.23.4"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Jeff Dwyer".freeze]
14
- s.date = "2023-04-07"
15
- s.description = "RateLimits & Config as a service".freeze
14
+ s.date = "2023-04-12"
15
+ s.description = "Feature Flags, Live Config, and Dynamic Log Levels as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE.txt",
@@ -33,8 +33,6 @@ Gem::Specification.new do |s|
33
33
  "VERSION",
34
34
  "compile_protos.sh",
35
35
  "lib/prefab-cloud-ruby.rb",
36
- "lib/prefab/auth_interceptor.rb",
37
- "lib/prefab/cancellable_interceptor.rb",
38
36
  "lib/prefab/client.rb",
39
37
  "lib/prefab/config_client.rb",
40
38
  "lib/prefab/config_loader.rb",
@@ -47,6 +45,7 @@ Gem::Specification.new do |s|
47
45
  "lib/prefab/errors/missing_default_error.rb",
48
46
  "lib/prefab/exponential_backoff.rb",
49
47
  "lib/prefab/feature_flag_client.rb",
48
+ "lib/prefab/http_connection.rb",
50
49
  "lib/prefab/internal_logger.rb",
51
50
  "lib/prefab/local_config_parser.rb",
52
51
  "lib/prefab/log_path_collector.rb",
@@ -55,7 +54,6 @@ Gem::Specification.new do |s|
55
54
  "lib/prefab/noop_cache.rb",
56
55
  "lib/prefab/noop_stats.rb",
57
56
  "lib/prefab/options.rb",
58
- "lib/prefab/ratelimit_client.rb",
59
57
  "lib/prefab/sse_logger.rb",
60
58
  "lib/prefab/weighted_value_resolver.rb",
61
59
  "lib/prefab/yaml_config_parser.rb",
@@ -96,12 +94,10 @@ Gem::Specification.new do |s|
96
94
  s.add_runtime_dependency(%q<faraday>.freeze, [">= 0"])
97
95
  s.add_runtime_dependency(%q<googleapis-common-protos-types>.freeze, [">= 0"])
98
96
  s.add_runtime_dependency(%q<google-protobuf>.freeze, [">= 0"])
99
- s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
100
97
  s.add_runtime_dependency(%q<ld-eventsource>.freeze, [">= 0"])
101
98
  s.add_runtime_dependency(%q<uuid>.freeze, [">= 0"])
102
99
  s.add_development_dependency(%q<benchmark-ips>.freeze, [">= 0"])
103
100
  s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
104
- s.add_development_dependency(%q<grpc-tools>.freeze, [">= 0"])
105
101
  s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
106
102
  s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
107
103
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
@@ -110,12 +106,10 @@ Gem::Specification.new do |s|
110
106
  s.add_dependency(%q<faraday>.freeze, [">= 0"])
111
107
  s.add_dependency(%q<googleapis-common-protos-types>.freeze, [">= 0"])
112
108
  s.add_dependency(%q<google-protobuf>.freeze, [">= 0"])
113
- s.add_dependency(%q<grpc>.freeze, [">= 0"])
114
109
  s.add_dependency(%q<ld-eventsource>.freeze, [">= 0"])
115
110
  s.add_dependency(%q<uuid>.freeze, [">= 0"])
116
111
  s.add_dependency(%q<benchmark-ips>.freeze, [">= 0"])
117
112
  s.add_dependency(%q<bundler>.freeze, [">= 0"])
118
- s.add_dependency(%q<grpc-tools>.freeze, [">= 0"])
119
113
  s.add_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
120
114
  s.add_dependency(%q<rdoc>.freeze, [">= 0"])
121
115
  s.add_dependency(%q<simplecov>.freeze, [">= 0"])
@@ -91,8 +91,7 @@ class IntegrationTest
91
91
  prefab_envs: ['unit_tests'],
92
92
  prefab_datasources: Prefab::Options::DATASOURCES::ALL,
93
93
  api_key: ENV['PREFAB_INTEGRATION_TEST_API_KEY'],
94
- prefab_api_url: 'https://api.staging-prefab.cloud',
95
- prefab_grpc_url: 'grpc.staging-prefab.cloud:443'
94
+ prefab_api_url: 'https://api.staging-prefab.cloud'
96
95
  }.merge(@client_overrides))
97
96
  end
98
97
  end
data/test/test_client.rb CHANGED
@@ -77,13 +77,6 @@ class TestClient < Minitest::Test
77
77
  assert_equal 'all-features', @client.get('flag_with_a_value')
78
78
  end
79
79
 
80
- def test_ssl_certs
81
- certs = @client.send(:ssl_certs).split('-----BEGIN CERTIFICATE-----')
82
-
83
- # This is a smoke test to make sure multiple certs are loaded
84
- assert certs.length > 1
85
- end
86
-
87
80
  def test_initialization_with_an_options_object
88
81
  options_hash = {
89
82
  namespace: 'test-namespace',
@@ -4,6 +4,9 @@ require 'test_helper'
4
4
  require 'timecop'
5
5
 
6
6
  class TestLogPathCollector < Minitest::Test
7
+ MAX_WAIT = 2
8
+ SLEEP_TIME = 0.01
9
+
7
10
  def test_sync
8
11
  Timecop.freeze do
9
12
  client = new_client(namespace: 'this.is.a.namespace')
@@ -13,29 +16,32 @@ class TestLogPathCollector < Minitest::Test
13
16
 
14
17
  requests = []
15
18
 
16
- client.define_singleton_method(:request) do |*params|
19
+ client.define_singleton_method(:post) do |*params|
17
20
  requests.push(params)
18
21
  end
19
22
 
20
23
  client.log_path_collector.send(:sync)
21
24
 
22
25
  # let the flush thread run
23
- sleep 0.01 while requests.length == 0
26
+
27
+ wait_time = 0
28
+ while requests.length == 0
29
+ wait_time += SLEEP_TIME
30
+ sleep SLEEP_TIME
31
+
32
+ raise "Waited #{MAX_WAIT} seconds for the flush thread to run, but it never did" if wait_time > MAX_WAIT
33
+ end
24
34
 
25
35
  assert_equal requests, [[
26
- Prefab::LoggerReportingService,
27
- :send,
28
- {
29
- req_options: {},
30
- params: Prefab::Loggers.new(
31
- loggers: [Prefab::Logger.new(logger_name: 'test.test_log_path_collector.test_sync',
32
- infos: 2, errors: 3)],
33
- start_at: (Time.now.utc.to_f * 1000).to_i,
34
- end_at: (Time.now.utc.to_f * 1000).to_i,
35
- instance_hash: client.instance_hash,
36
- namespace: 'this.is.a.namespace'
37
- )
38
- }
36
+ '/api/v1/known-loggers',
37
+ Prefab::Loggers.new(
38
+ loggers: [Prefab::Logger.new(logger_name: 'test.test_log_path_collector.test_sync',
39
+ infos: 2, errors: 3)],
40
+ start_at: (Time.now.utc.to_f * 1000).to_i,
41
+ end_at: (Time.now.utc.to_f * 1000).to_i,
42
+ instance_hash: client.instance_hash,
43
+ namespace: 'this.is.a.namespace'
44
+ )
39
45
  ]]
40
46
  end
41
47
  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.23.3
4
+ version: 0.23.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-07 00:00:00.000000000 Z
11
+ date: 2023-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -72,20 +72,6 @@ dependencies:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
- - !ruby/object:Gem::Dependency
76
- name: grpc
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: '0'
82
- type: :runtime
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- version: '0'
89
75
  - !ruby/object:Gem::Dependency
90
76
  name: ld-eventsource
91
77
  requirement: !ruby/object:Gem::Requirement
@@ -142,20 +128,6 @@ dependencies:
142
128
  - - ">="
143
129
  - !ruby/object:Gem::Version
144
130
  version: '0'
145
- - !ruby/object:Gem::Dependency
146
- name: grpc-tools
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - ">="
150
- - !ruby/object:Gem::Version
151
- version: '0'
152
- type: :development
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - ">="
157
- - !ruby/object:Gem::Version
158
- version: '0'
159
131
  - !ruby/object:Gem::Dependency
160
132
  name: juwelier
161
133
  requirement: !ruby/object:Gem::Requirement
@@ -198,7 +170,7 @@ dependencies:
198
170
  - - ">="
199
171
  - !ruby/object:Gem::Version
200
172
  version: '0'
201
- description: RateLimits & Config as a service
173
+ description: Feature Flags, Live Config, and Dynamic Log Levels as a service
202
174
  email: jdwyer@prefab.cloud
203
175
  executables: []
204
176
  extensions: []
@@ -220,8 +192,6 @@ files:
220
192
  - VERSION
221
193
  - compile_protos.sh
222
194
  - lib/prefab-cloud-ruby.rb
223
- - lib/prefab/auth_interceptor.rb
224
- - lib/prefab/cancellable_interceptor.rb
225
195
  - lib/prefab/client.rb
226
196
  - lib/prefab/config_client.rb
227
197
  - lib/prefab/config_loader.rb
@@ -234,6 +204,7 @@ files:
234
204
  - lib/prefab/errors/missing_default_error.rb
235
205
  - lib/prefab/exponential_backoff.rb
236
206
  - lib/prefab/feature_flag_client.rb
207
+ - lib/prefab/http_connection.rb
237
208
  - lib/prefab/internal_logger.rb
238
209
  - lib/prefab/local_config_parser.rb
239
210
  - lib/prefab/log_path_collector.rb
@@ -242,7 +213,6 @@ files:
242
213
  - lib/prefab/noop_cache.rb
243
214
  - lib/prefab/noop_stats.rb
244
215
  - lib/prefab/options.rb
245
- - lib/prefab/ratelimit_client.rb
246
216
  - lib/prefab/sse_logger.rb
247
217
  - lib/prefab/weighted_value_resolver.rb
248
218
  - lib/prefab/yaml_config_parser.rb
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class AuthInterceptor < GRPC::ClientInterceptor
5
- VERSION = File.exist?('VERSION') ? File.read('VERSION').chomp : ''
6
- CLIENT = "prefab-cloud-ruby.#{VERSION}".freeze
7
-
8
- def initialize(api_key)
9
- @api_key = api_key
10
- end
11
-
12
- def request_response(request:, call:, method:, metadata:, &block)
13
- shared(metadata, &block)
14
- end
15
-
16
- def client_streamer(requests:, call:, method:, metadata:, &block)
17
- shared(metadata, &block)
18
- end
19
-
20
- def server_streamer(request:, call:, method:, metadata:, &block)
21
- shared(metadata, &block)
22
- end
23
-
24
- def bidi_streamer(requests:, call:, method:, metadata:, &block)
25
- shared(metadata, &block)
26
- end
27
-
28
- def shared(metadata)
29
- metadata['auth'] = @api_key
30
- metadata['client'] = CLIENT
31
- yield
32
- end
33
- end
34
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class CancellableInterceptor < GRPC::ClientInterceptor
5
- WAIT_SEC = 3
6
-
7
- def initialize(base_client)
8
- @base_client = base_client
9
- end
10
-
11
- def cancel
12
- @call.instance_variable_get('@wrapped').instance_variable_get('@call').cancel
13
- i = 0
14
- while i < WAIT_SEC
15
- if @call.instance_variable_get('@wrapped').cancelled?
16
- @base_client.log_internal ::Logger::DEBUG, 'Cancelled streaming.'
17
- return
18
- else
19
- @base_client.log_internal ::Logger::DEBUG, 'Unable to cancel streaming. Trying again'
20
- @call.instance_variable_get('@wrapped').instance_variable_get('@call').cancel
21
- i += 1
22
- sleep(1)
23
- end
24
- end
25
- @base_client.log_internal ::Logger::INFO, 'Unable to cancel streaming.'
26
- end
27
-
28
- def request_response(request:, call:, method:, metadata:, &block)
29
- shared(call, &block)
30
- end
31
-
32
- def client_streamer(requests:, call:, method:, metadata:, &block)
33
- shared(call, &block)
34
- end
35
-
36
- def server_streamer(request:, call:, method:, metadata:, &block)
37
- shared(call, &block)
38
- end
39
-
40
- def bidi_streamer(requests:, call:, method:, metadata:, &block)
41
- shared(call, &block)
42
- end
43
-
44
- def shared(call)
45
- @call = call
46
- yield
47
- end
48
- end
49
- end
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class RateLimitClient
5
- def initialize(base_client, timeout)
6
- @timeout = timeout
7
- @base_client = base_client
8
- end
9
-
10
- def pass?(group)
11
- result = acquire([group], 1)
12
- result.passed
13
- end
14
-
15
- def acquire(groups, acquire_amount, allow_partial_response: false, on_error: :log_and_pass)
16
- expiry_cache_key = "prefab.ratelimit.expiry:#{groups.join('.')}"
17
- expiry = @base_client.shared_cache.read(expiry_cache_key)
18
- if !expiry.nil? && Integer(expiry) > Time.now.utc.to_f * 1000
19
- @base_client.stats.increment('prefab.ratelimit.limitcheck.expirycache.hit', tags: [])
20
- return Prefab::LimitResponse.new(passed: false, amount: 0)
21
- end
22
-
23
- req = Prefab::LimitRequest.new(
24
- account_id: @base_client.account_id,
25
- acquire_amount: acquire_amount,
26
- groups: groups,
27
- allow_partial_response: allow_partial_response
28
- )
29
-
30
- result = @base_client.request Prefab::RateLimitService, :limit_check, req_options: { timeout: @timeout },
31
- params: req
32
-
33
- reset = result.limit_reset_at
34
- @base_client.shared_cache.write(expiry_cache_key, reset) unless reset < 1 # protobuf default int to 0
35
-
36
- @base_client.stats.increment('prefab.ratelimit.limitcheck',
37
- tags: ["policy_group:#{result.policy_group}", "pass:#{result.passed}"])
38
-
39
- result
40
- rescue StandardError => e
41
- handle_error(e, on_error, groups)
42
- end
43
-
44
- def upsert(key, policy_name, limit, burst: nil, safety_level: nil)
45
- burst = limit if burst.nil?
46
- limit_definition = Prefab::LimitDefinition.new(
47
- account_id: @base_client.account_id,
48
- policy_name: Object.const_get("Prefab::LimitResponse::LimitPolicyNames::#{policy_name}"),
49
- limit: limit,
50
- burst: burst
51
- )
52
- limit_definition.safety_level = safety_level unless safety_level.nil?
53
- config_value = Prefab::ConfigValue.new(limit_definition: limit_definition)
54
- config_delta = Prefab::ConfigClient.value_to_delta(key, config_value)
55
- upsert_req = Prefab::UpsertRequest.new(config_delta: config_delta)
56
-
57
- @base_client.request Prefab::ConfigService, :upsert, req_options: { timeout: @timeout }, params: upsert_req
58
- end
59
-
60
- private
61
-
62
- def handle_error(e, on_error, groups)
63
- @base_client.stats.increment('prefab.ratelimit.error', tags: ['type:limit'])
64
-
65
- message = "ratelimit for #{groups} error: #{e.message}"
66
- case on_error
67
- when :log_and_pass
68
- @base_client.log.warn(message)
69
- Prefab::LimitResponse.new(passed: true, amount: 0)
70
- when :log_and_hit
71
- @base_client.log.warn(message)
72
- Prefab::LimitResponse.new(passed: false, amount: 0)
73
- when :throw
74
- raise e
75
- end
76
- end
77
- end
78
- end