prefab-cloud-ruby 0.0.13 → 0.0.14

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: 4e22f15bdc4f3f3d98d0a397e0685a7b457231cc
4
- data.tar.gz: 3a1b5af166637f72160e1fdea3ed2f0d08aa2ded
3
+ metadata.gz: 70b7e6905adede604544ce942c02d4b77c8e368b
4
+ data.tar.gz: 9b5091d9df705f1c8dd01ab7bc218ac0bcdada04
5
5
  SHA512:
6
- metadata.gz: a94a74cc16025df1c4cf0cdf2a1a8b1aa1f7b501bb9aba66d7643ba643ed96f82b840adabed2f14a3038a5f10aac4641557869777da0cf56d842dfcb1e3d9e06
7
- data.tar.gz: 9c659f681aa37174f81967e8a698fbf796f87c4d12bc647353e5e30b0266b6e6f0a127ace4fe342bb4d55c97fdf83957559ad95ff750c4b81310e6cd3a6957e5
6
+ metadata.gz: 75fb25229c3523976b4048c4bbc220705486062620c8f51951ff41cb80c0b575cb4bbab1cf792366c108c553b94a00a0f89b594e328d725eeb7a58bce8990865
7
+ data.tar.gz: a8cc43a7a3e102bd4bfe131f93e3ff0eb0a389cc3e8ba10357d426aefd5608ebcee9269cc6ca228ae059ee0b8ec590e09fa7a68cb5f383c176254563df4e0817
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.13
1
+ 0.0.14
@@ -13,6 +13,5 @@ require 'prefab/logger_client'
13
13
  require 'prefab/auth_interceptor'
14
14
  require 'prefab/noop_cache'
15
15
  require 'prefab/noop_stats'
16
- require 'prefab/retry'
17
16
  require 'prefab/murmer3'
18
17
 
@@ -1,5 +1,9 @@
1
1
  module Prefab
2
2
  class Client
3
+
4
+ MAX_SLEEP_SEC = 10
5
+ BASE_SLEEP_SEC = 0.5
6
+
3
7
  attr_reader :account_id, :shared_cache, :stats, :namespace, :creds, :interceptor
4
8
 
5
9
  def initialize(api_key: ENV['PREFAB_API_KEY'],
@@ -21,8 +25,8 @@ module Prefab
21
25
  @namespace = namespace
22
26
 
23
27
  @interceptor = AuthInterceptor.new(api_key)
24
-
25
28
  @creds = GRPC::Core::ChannelCredentials.new(ssl_certs)
29
+ @stubs = {}
26
30
  end
27
31
 
28
32
  def channel
@@ -38,7 +42,7 @@ module Prefab
38
42
 
39
43
  def config_client(timeout: 5.0)
40
44
  @config_client ||= Prefab::ConfigClient.new(self, timeout)
41
- @config_init = true
45
+ @config_client.init
42
46
  @config_client
43
47
  end
44
48
 
@@ -51,12 +55,53 @@ module Prefab
51
55
  end
52
56
 
53
57
  def log(base_logger = @logger)
54
- return @logger if !@config_init
55
58
  @logger_client || Prefab::LoggerClient.new(self, base_logger)
56
59
  end
57
60
 
61
+ def log_internal(level, msg)
62
+ log.log_for level, msg, "prefab"
63
+ end
64
+
65
+ def request(service, method, req_options: {}, params: {})
66
+ opts = { timeout: 10 }.merge(req_options)
67
+
68
+ attempts = 0
69
+ start_time = Time.now
70
+
71
+ begin
72
+ attempts += 1
73
+ return stub_for(service).send(method, *params)
74
+ rescue => exception
75
+
76
+ log_internal :warn, exception
77
+
78
+ if Time.now - start_time > opts[:timeout]
79
+ raise exception
80
+ end
81
+ sleep_seconds = [BASE_SLEEP_SEC * (2 ** (attempts - 1)), MAX_SLEEP_SEC].min
82
+ sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
83
+ sleep_seconds = [BASE_SLEEP_SEC, sleep_seconds].max
84
+ log_internal :info, "Sleep #{sleep_seconds} and Reset #{service} #{method}"
85
+ sleep sleep_seconds
86
+ reset!
87
+ retry
88
+ end
89
+ end
90
+
58
91
  private
59
92
 
93
+ def reset!
94
+ @stubs.clear
95
+ reset_channel!
96
+ end
97
+
98
+ def stub_for(service)
99
+ @stubs[service] ||= service::Stub.new(nil,
100
+ nil,
101
+ channel_override: channel,
102
+ interceptors: [@interceptor])
103
+ end
104
+
60
105
  def ssl_certs
61
106
  ssl_certs = ""
62
107
  Dir["#{OpenSSL::X509::DEFAULT_CERT_DIR}/*.pem"].each do |cert|
@@ -7,16 +7,23 @@ module Prefab
7
7
  def initialize(base_client, timeout)
8
8
  @base_client = base_client
9
9
  @timeout = timeout
10
- @config_loader = Prefab::ConfigLoader.new(base_client)
11
- @config_resolver = Prefab::ConfigResolver.new(base_client, @config_loader)
12
- start_at_id = load_checkpoint
13
- start_api_connection_thread(start_at_id)
14
- start_checkpointing_thread
15
- start_suspenders_thread
10
+ @initialized = false
11
+ end
12
+
13
+ def init
14
+ if !@initialized
15
+ @initialized = true
16
+ @config_loader = Prefab::ConfigLoader.new(@base_client)
17
+ @config_resolver = Prefab::ConfigResolver.new(@base_client, @config_loader)
18
+ start_at_id = load_checkpoint
19
+ start_api_connection_thread(start_at_id)
20
+ start_checkpointing_thread
21
+ start_suspenders_thread
22
+ end
16
23
  end
17
24
 
18
25
  def get(prop)
19
- @config_resolver.get(prop)
26
+ @config_resolver.get(prop) if @config_resolver
20
27
  end
21
28
 
22
29
  def upsert(key, config_value, namespace = nil, previous_key = nil)
@@ -26,7 +33,8 @@ module Prefab
26
33
  upsert_req = Prefab::UpsertRequest.new(config_delta: config_delta)
27
34
  upsert_req.previous_key = previous_key if previous_key&.present?
28
35
 
29
- Retry.it method(:stub_with_timeout), :upsert, upsert_req, @timeout, method(:reset)
36
+ @base_client.request Prefab::ConfigService, :upsert, req_options: {timeout: @timeout}, params: upsert_req
37
+
30
38
  @config_loader.set(config_delta)
31
39
  @config_loader.rm(previous_key) if previous_key&.present?
32
40
  @config_resolver.update
@@ -35,7 +43,6 @@ module Prefab
35
43
  def reset
36
44
  @base_client.reset_channel!
37
45
  @_stub = nil
38
- @_stub_with_timeout = nil
39
46
  end
40
47
 
41
48
  def to_s
@@ -56,14 +63,6 @@ module Prefab
56
63
  interceptors: [@base_client.interceptor])
57
64
  end
58
65
 
59
- def stub_with_timeout
60
- @_stub_with_timeout = Prefab::ConfigService::Stub.new(nil,
61
- nil,
62
- channel_override: @base_client.channel,
63
- timeout: @timeout,
64
- interceptors: [@base_client.interceptor])
65
- end
66
-
67
66
  def cache_key
68
67
  "prefab:config:checkpoint"
69
68
  end
@@ -77,14 +76,14 @@ module Prefab
77
76
  if checkpoint
78
77
  deltas = Prefab::ConfigDeltas.decode(checkpoint)
79
78
  deltas.deltas.each do |delta|
80
- @base_client.log.debug "checkpoint set #{delta.key} #{delta.value.int} #{delta.value.string} #{delta.id} "
79
+ @base_client.log_internal :debug, "checkpoint set #{delta.key} #{delta.value.int} #{delta.value.string} #{delta.id} "
81
80
  @config_loader.set(delta)
82
81
  start_at_id = [delta.id, start_at_id].max
83
82
  end
84
- @base_client.log.info "Found checkpoint with highwater id #{start_at_id}"
83
+ @base_client.log_internal :info, "Found checkpoint with highwater id #{start_at_id}"
85
84
  @config_resolver.update
86
85
  else
87
- @base_client.log.info "No checkpoint"
86
+ @base_client.log_internal :info, "No checkpoint"
88
87
  end
89
88
 
90
89
  start_at_id
@@ -101,10 +100,10 @@ module Prefab
101
100
  sleep(delta)
102
101
  end
103
102
  deltas = @config_resolver.export_api_deltas
104
- @base_client.log.debug "==CHECKPOINT==#{deltas.deltas.map {|d| d.id}.max}===#{Thread.current.object_id}=="
103
+ @base_client.log_internal :debug, "Save Checkpoint #{deltas.deltas.map {|d| d.id}.max} Thread #{Thread.current.object_id}"
105
104
  @base_client.shared_cache.write(cache_key, Prefab::ConfigDeltas.encode(deltas))
106
105
  rescue StandardError => exn
107
- @base_client.log.info "Issue Checkpointing #{exn.message}"
106
+ @base_client.log_internal :info, "Issue Checkpointing #{exn.message}"
108
107
  end
109
108
  end
110
109
  end
@@ -126,7 +125,7 @@ module Prefab
126
125
  @config_resolver.update
127
126
  end
128
127
  rescue => e
129
- @base_client.log.info("config client encountered #{e.message} pausing #{RECONNECT_WAIT}")
128
+ @base_client.log_internal :info, ("config client encountered #{e.message} pausing #{RECONNECT_WAIT}")
130
129
  reset
131
130
  sleep(RECONNECT_WAIT)
132
131
  end
@@ -145,7 +144,9 @@ module Prefab
145
144
  started_at = Time.now
146
145
  config_req = Prefab::ConfigServicePointer.new(account_id: @base_client.account_id,
147
146
  start_at_id: start_at_suspenders)
148
- resp = stub_with_timeout.get_config(config_req)
147
+
148
+ resp = @base_client.request Prefab::ConfigService, :get_config, req_options: {timeout: @timeout}, params: config_req
149
+
149
150
  resp.each do |r|
150
151
  r.deltas.each do |delta|
151
152
  @config_loader.set(delta)
@@ -155,7 +156,7 @@ module Prefab
155
156
  rescue GRPC::DeadlineExceeded
156
157
  # Ignore. This is a streaming endpoint, but we only need a single response
157
158
  rescue => e
158
- @base_client.log.info "Suspenders encountered an issue #{e.message}"
159
+ @base_client.log_internal :info, "Suspenders encountered an issue #{e.message}"
159
160
  end
160
161
 
161
162
  delta = SUSPENDERS_FREQ_SEC - (Time.now - started_at)
@@ -62,9 +62,10 @@ module Prefab
62
62
 
63
63
  def load(filename)
64
64
  if File.exist? filename
65
+ @base_client.log_internal :warn, "Load #{filename}"
65
66
  YAML.load_file(filename)
66
67
  else
67
- @base_client.logger.info "No file #{filename}"
68
+ @base_client.log_internal :warn, "No file #{filename}"
68
69
  {}
69
70
  end
70
71
  end
@@ -1,40 +1,58 @@
1
1
  module Prefab
2
2
  class LoggerClient
3
3
 
4
+ SEP = ".".freeze
5
+ BASE = "log_level".freeze
6
+
4
7
  def initialize(base_client, base_logger)
5
8
  @base_client = base_client
6
9
  @base_logger = base_logger
7
10
  end
8
11
 
9
- def info msg
10
- pf_log :info, msg, caller_locations(1, 1)[0]
11
- end
12
-
13
12
  def debug msg
14
13
  pf_log :debug, msg, caller_locations(1, 1)[0]
15
14
  end
16
15
 
16
+ def info msg
17
+ pf_log :info, msg, caller_locations(1, 1)[0]
18
+ end
19
+
17
20
  def warn msg
18
21
  pf_log :warn, msg, caller_locations(1, 1)[0]
19
22
  end
20
23
 
21
- def pf_log level, msg, loc
22
- path = loc.absolute_path + ""
24
+ def error msg
25
+ pf_log :error, msg, caller_locations(1, 1)[0]
26
+ end
27
+
28
+ def log_for level, msg, loc
29
+ pf_log_internal level, msg, "", loc
30
+ end
31
+
32
+ private
33
+
34
+ def pf_log(level, msg, loc)
35
+ pf_log_internal level, msg, loc.absolute_path, loc.base_label
36
+ end
37
+
38
+ def pf_log_internal(level, msg, absolute_path, base_label)
39
+
40
+ path = absolute_path + ""
23
41
  path.slice! Dir.pwd
24
42
 
25
- path = "#{path.gsub("/", ":").gsub(".rb", "")}:#{loc.base_label}"
26
- path.slice! ":"
43
+ path = "#{path.gsub("/", SEP).gsub(".rb", "")}#{SEP}#{base_label}"
44
+ path.slice! SEP
27
45
 
28
- base = "log_level"
29
- closest_log_level_match = @base_client.config_client.get(base) || :warn
30
- path.split(":").inject([base]) do |memo, n|
46
+ closest_log_level_match = @base_client.config_client.get(BASE) || :warn
47
+ path.split(SEP).inject([BASE]) do |memo, n|
31
48
  memo << n
32
- val = @base_client.config_client.get memo.join(".")
49
+ val = @base_client.config_client.get memo.join(SEP)
33
50
  unless val.nil?
34
51
  closest_log_level_match = val
35
52
  end
36
53
  memo
37
54
  end
55
+
38
56
  if val(closest_log_level_match) <= val(level)
39
57
  @base_logger.unknown "#{level.to_s.upcase.ljust(5)} #{path} #{msg}"
40
58
  end
@@ -26,7 +26,7 @@ module Prefab
26
26
  allow_partial_response: allow_partial_response
27
27
  )
28
28
 
29
- result = Retry.it(method(:stub), :limit_check, req, @timeout, method(:reset))
29
+ result = @base_client.request Prefab::RateLimitService, :limit_check, req_options: {timeout: @timeout}, params: req
30
30
 
31
31
  reset = result.limit_reset_at
32
32
  @base_client.shared_cache.write(expiry_cache_key, reset) unless reset < 1 # protobuf default int to 0
@@ -41,19 +41,6 @@ module Prefab
41
41
 
42
42
  private
43
43
 
44
- def reset
45
- @base_client.reset_channel!
46
- @_stub = nil
47
- end
48
-
49
- def stub
50
- @_stub ||= Prefab::RateLimitService::Stub.new(nil,
51
- nil,
52
- channel_override: @base_client.channel,
53
- timeout: @timeout,
54
- interceptors: [@base_client.interceptor])
55
- end
56
-
57
44
  def handle_error(e, on_error, groups)
58
45
  @base_client.stats.increment("prefab.ratelimit.error", tags: ["type:limit"])
59
46
 
@@ -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.0.13 ruby lib
5
+ # stub: prefab-cloud-ruby 0.0.14 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.0.13"
9
+ s.version = "0.0.14"
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 = "2018-02-13"
14
+ s.date = "2018-02-20"
15
15
  s.description = "RateLimits & Config as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -37,7 +37,6 @@ Gem::Specification.new do |s|
37
37
  "lib/prefab/noop_cache.rb",
38
38
  "lib/prefab/noop_stats.rb",
39
39
  "lib/prefab/ratelimit_client.rb",
40
- "lib/prefab/retry.rb",
41
40
  "lib/prefab_pb.rb",
42
41
  "lib/prefab_services_pb.rb",
43
42
  "prefab-cloud-ruby.gemspec",
@@ -3,3 +3,4 @@ sample_int: 123
3
3
  sample_double: 12.12
4
4
  sample_bool: true
5
5
  sample_to_override: Foo
6
+ prefab.log_level: debug
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.0.13
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-13 00:00:00.000000000 Z
11
+ date: 2018-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc
@@ -154,7 +154,6 @@ files:
154
154
  - lib/prefab/noop_cache.rb
155
155
  - lib/prefab/noop_stats.rb
156
156
  - lib/prefab/ratelimit_client.rb
157
- - lib/prefab/retry.rb
158
157
  - lib/prefab_pb.rb
159
158
  - lib/prefab_services_pb.rb
160
159
  - prefab-cloud-ruby.gemspec
@@ -1,28 +0,0 @@
1
- class Retry
2
- MAX_SLEEP_SEC = 10
3
- BASE_SLEEP_SEC = 0.5
4
-
5
- # GRPC Generally handles timeouts for us
6
- # but if the connection is broken we want to retry up until the timeout
7
- def self.it(stub_factory, rpc, req, timeout, reset)
8
- attempts = 0
9
- start_time = Time.now
10
-
11
- begin
12
- attempts += 1
13
- return stub_factory.call.send(rpc, req)
14
- rescue => exception
15
-
16
- if Time.now - start_time > timeout
17
- raise exception
18
- end
19
- sleep_seconds = [BASE_SLEEP_SEC * (2 ** (attempts - 1)), MAX_SLEEP_SEC].min
20
- sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
21
- sleep_seconds = [BASE_SLEEP_SEC, sleep_seconds].max
22
- puts "Sleep #{sleep_seconds} and Reset"
23
- sleep sleep_seconds
24
- reset.call
25
- retry
26
- end
27
- end
28
- end