prefab-cloud-ruby 0.24.3 → 0.24.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.rubocop.yml +13 -0
  4. data/CHANGELOG.md +78 -0
  5. data/Gemfile.lock +4 -4
  6. data/VERSION +1 -1
  7. data/bin/console +21 -0
  8. data/compile_protos.sh +6 -0
  9. data/lib/prefab/client.rb +25 -4
  10. data/lib/prefab/config_client.rb +17 -6
  11. data/lib/prefab/config_loader.rb +1 -1
  12. data/lib/prefab/config_resolver.rb +2 -4
  13. data/lib/prefab/config_value_wrapper.rb +18 -0
  14. data/lib/prefab/context.rb +22 -2
  15. data/lib/prefab/context_shape.rb +20 -0
  16. data/lib/prefab/context_shape_aggregator.rb +63 -0
  17. data/lib/prefab/criteria_evaluator.rb +61 -41
  18. data/lib/prefab/evaluated_configs_aggregator.rb +60 -0
  19. data/lib/prefab/evaluated_keys_aggregator.rb +41 -0
  20. data/lib/prefab/http_connection.rb +5 -1
  21. data/lib/prefab/local_config_parser.rb +13 -13
  22. data/lib/prefab/log_path_aggregator.rb +64 -0
  23. data/lib/prefab/logger_client.rb +11 -13
  24. data/lib/prefab/options.rb +37 -1
  25. data/lib/prefab/periodic_sync.rb +51 -0
  26. data/lib/prefab/time_helpers.rb +7 -0
  27. data/lib/prefab-cloud-ruby.rb +9 -2
  28. data/lib/prefab_pb.rb +33 -220
  29. data/prefab-cloud-ruby.gemspec +21 -5
  30. data/test/test_config_loader.rb +15 -15
  31. data/test/test_config_resolver.rb +102 -102
  32. data/test/test_config_value_unwrapper.rb +13 -13
  33. data/test/test_context.rb +42 -0
  34. data/test/test_context_shape.rb +51 -0
  35. data/test/test_context_shape_aggregator.rb +137 -0
  36. data/test/test_criteria_evaluator.rb +253 -150
  37. data/test/test_evaluated_configs_aggregator.rb +254 -0
  38. data/test/test_evaluated_keys_aggregator.rb +54 -0
  39. data/test/test_helper.rb +34 -2
  40. data/test/test_log_path_aggregator.rb +57 -0
  41. data/test/test_logger.rb +33 -33
  42. data/test/test_weighted_value_resolver.rb +2 -2
  43. metadata +21 -5
  44. data/lib/prefab/log_path_collector.rb +0 -102
  45. data/test/test_log_path_collector.rb +0 -58
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class LogPathCollector
5
- INCREMENT = ->(count) { (count || 0) + 1 }
6
-
7
- SEVERITY_KEY = {
8
- ::Logger::DEBUG => 'debugs',
9
- ::Logger::INFO => 'infos',
10
- ::Logger::WARN => 'warns',
11
- ::Logger::ERROR => 'errors',
12
- ::Logger::FATAL => 'fatals'
13
- }.freeze
14
-
15
- def initialize(client:, max_paths:, sync_interval:)
16
- @max_paths = max_paths
17
- @client = client
18
- @start_at = now
19
- @sync_interval = if sync_interval.is_a?(Numeric)
20
- proc { sync_interval }
21
- else
22
- sync_interval || ExponentialBackoff.new(initial_delay: 8, max_delay: 60 * 10)
23
- end
24
-
25
- @pool = Concurrent::ThreadPoolExecutor.new(
26
- fallback_policy: :discard,
27
- max_queue: 5,
28
- max_threads: 4,
29
- min_threads: 1,
30
- name: 'prefab-log-paths'
31
- )
32
-
33
- @paths = Concurrent::Map.new
34
-
35
- start_periodic_sync
36
- end
37
-
38
- def push(path, severity)
39
- return unless @paths.size < @max_paths
40
-
41
- @paths.compute([path, severity], &INCREMENT)
42
- end
43
-
44
- private
45
-
46
- def sync
47
- return if @paths.size.zero?
48
-
49
- log_internal "Syncing #{@paths.size} paths"
50
-
51
- flush
52
- end
53
-
54
- def flush
55
- to_ship = @paths.dup
56
- @paths.clear
57
-
58
- start_at_was = @start_at
59
- @start_at = now
60
-
61
- @pool.post do
62
- log_internal "Uploading stats for #{to_ship.size} paths"
63
-
64
- aggregate = Hash.new { |h, k| h[k] = Prefab::Logger.new }
65
-
66
- to_ship.each do |(path, severity), count|
67
- aggregate[path][SEVERITY_KEY[severity]] = count
68
- aggregate[path]['logger_name'] = path
69
- end
70
-
71
- loggers = Prefab::Loggers.new(
72
- loggers: aggregate.values,
73
- start_at: start_at_was,
74
- end_at: now,
75
- instance_hash: @client.instance_hash,
76
- namespace: @client.namespace
77
- )
78
-
79
- @client.post('/api/v1/known-loggers', loggers)
80
- end
81
- end
82
-
83
- def start_periodic_sync
84
- Thread.new do
85
- log_internal "Initialized log path collector instance_hash=#{@client.instance_hash} max_paths=#{@max_paths}"
86
-
87
- loop do
88
- sleep @sync_interval.call
89
- sync
90
- end
91
- end
92
- end
93
-
94
- def log_internal(message)
95
- @client.log.log_internal message, 'log_path_collector', nil, ::Logger::DEBUG
96
- end
97
-
98
- def now
99
- (Time.now.utc.to_f * 1000).to_i
100
- end
101
- end
102
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
- require 'timecop'
5
-
6
- class TestLogPathCollector < Minitest::Test
7
- MAX_WAIT = 2
8
- SLEEP_TIME = 0.01
9
-
10
- def test_sync
11
- Timecop.freeze do
12
- client = new_client(namespace: 'this.is.a.namespace')
13
-
14
- 2.times { client.log.info('here is a message') }
15
- 3.times { client.log.error('here is a message') }
16
-
17
- requests = []
18
-
19
- client.define_singleton_method(:post) do |*params|
20
- requests.push(params)
21
- end
22
-
23
- client.log_path_collector.send(:sync)
24
-
25
- # let the flush thread run
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
34
-
35
- assert_equal requests, [[
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
- )
45
- ]]
46
- end
47
- end
48
-
49
- private
50
-
51
- def new_client(overrides = {})
52
- super(**{
53
- prefab_datasources: Prefab::Options::DATASOURCES::ALL,
54
- api_key: '123-development-yourapikey-SDK',
55
- collect_sync_interval: 1000 # we'll trigger sync manually in our test
56
- }.merge(overrides))
57
- end
58
- end