prefab-cloud-ruby 0.23.3 → 0.23.4

Sign up to get free protection for your applications and to get access to all the features.
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