rookout 0.1.38 → 0.1.39

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: e7230e6476d46d4184cd1887296f946c67fcc2e5e35b3b404f9f66444ef4d964
4
- data.tar.gz: '098f43b827ae84b56adb3e19905899487d3082ce66862b1938bf823ec2cee7de'
3
+ metadata.gz: fb5d9fef64ead13081355d267ad49671d0ca9ddf3e916ab5cf556d6d3b5997be
4
+ data.tar.gz: e114be3eb5224761c01f5a64bd4f367a90effed5d130c61f90ab4a8328152928
5
5
  SHA512:
6
- metadata.gz: 81e11a89868203775659bcab8b1a9ac4141cba01ca33ab6bd3f33f71d4be46c39f2652d1b3a2c413260104cf8b215c448ba8251081bb2e389fe32c12238fe5c4
7
- data.tar.gz: 22c3bbe9a67a1cefa8cc1928c4882fb585c479bb0e36b75c4ebf9abe0c7b5839e364169347b7c37b8dd40aec14641449e7ddf55db968378e9f2bcc876c9bcf4e
6
+ metadata.gz: 1da019cfc4c4cbeada393163a6fb4fa01826fdfe9d76edfd0926218b40d6dbedafb2291de4c63a558ac521bf6d360fee76a8522b2a10d021ce7d3538ce1ae530
7
+ data.tar.gz: 0a24f0bee3b44a23c9ad1ab7e1cdd6c6fc694e50358abd9d96b219ab3a5116c6567ebfd94a498de0de3cda523605fe2d0d27617d3aca7a9161689eeaa9132131
@@ -10,13 +10,11 @@ module Rookout
10
10
  require_relative "../logger"
11
11
 
12
12
  class Aug
13
- def initialize aug_id, action, condition, rate_limiter, _max_aug_time
14
- # NOTE: max_aux_time is not implemented
15
-
13
+ def initialize aug_id, action, condition, limits_manager, _max_aug_time
16
14
  @id = aug_id
17
15
  @action = action
18
16
  @condition = condition
19
- @rate_limiter = rate_limiter
17
+ @limits_manager = limits_manager
20
18
 
21
19
  @enabled = true
22
20
  @status = nil
@@ -36,7 +34,7 @@ module Rookout
36
34
  namespace = create_namespaces frame, extracted
37
35
  return if @condition && !@condition.evaluate(namespace)
38
36
 
39
- @rate_limiter.with_limit do
37
+ @limits_manager.with_limit do
40
38
  report_id = Utils.uuid
41
39
  Logger.instance.info "Executing aug-\t#{id} (msg ID #{report_id})"
42
40
  @action.execute @id, report_id, namespace, output
@@ -10,7 +10,9 @@ module Rookout
10
10
  require_relative "locations/location_exception_handler"
11
11
  require_relative "aug_rate_limiter"
12
12
  require_relative "aug"
13
+ require_relative "limits_manager"
13
14
  require_relative "../utils"
15
+ require_relative "../logger"
14
16
 
15
17
  class AugFactory
16
18
  def initialize output
@@ -34,10 +36,10 @@ module Rookout
34
36
  end
35
37
  condition = condition_configuration.nil? ? nil : Conditions::Condition.new(condition_configuration)
36
38
 
37
- rate_limit = create_rate_limit configuration
39
+ limits_manager = create_limits_manager configuration
38
40
 
39
41
  max_aug_time_ns = Utils.milliseconds_to_nanoseconds max_aug_time
40
- aug = Aug.new aug_id, action, condition, rate_limit, max_aug_time_ns
42
+ aug = Aug.new aug_id, action, condition, limits_manager, max_aug_time_ns
41
43
 
42
44
  location_configuration = configuration["location"]
43
45
  raise Exceptions::RookAugInvalidKey.new("location", configuration) unless location_configuration.is_a? Hash
@@ -62,25 +64,47 @@ module Rookout
62
64
  end
63
65
  end
64
66
 
65
- def create_rate_limit configuration
66
- window_quota = 200
67
- window_size = 5000
67
+ def create_limits_manager configuration
68
+ limiters = []
69
+ if global_rate_limiter.nil?
70
+ rate_limit = parse_rate_limit configuration["rateLimit"], configuration["rateLimitModifier"], 200, 5000
71
+ limiters.append AugRateLimiter.new(*rate_limit)
72
+ else
73
+ limiters.append global_rate_limiter
74
+ end
68
75
 
69
- rate_limit = configuration["rateLimit"]
70
- if rate_limit
71
- rate_limit_splitted = rate_limit.split "/"
72
- if rate_limit_splitted.length == 2
73
- window_quota = rate_limit_splitted[0].to_i
74
- window_size = rate_limit_splitted[1].to_i
75
- end
76
+ LimitsManager.new limiters
77
+ end
78
+
79
+ def global_rate_limiter
80
+ if @global_rate_limiter.nil? && !Rookout::Config.global_rate_limit.nil?
81
+ rate_limit = parse_rate_limit Rookout::Config.global_rate_limit, "0", 0, 0
82
+ @global_rate_limiter = AugRateLimiter.new(*rate_limit)
83
+ Logger.instance.debug "Using global rate limiter with configuration: #{rate_limit}"
76
84
  end
77
85
 
78
- rate_limit_modifier = configuration["rateLimitModifier"] || 5
86
+ @global_rate_limiter
87
+ end
88
+
89
+ def parse_rate_limit config, modifier_config, default_quota, default_window
90
+ window_quota = default_quota
91
+ window_size = default_window
92
+
93
+ unless config.nil? || config.empty?
94
+ rate_limit_split = config.split "/"
95
+ unless rate_limit_split.length == 2 && rate_limit_split[0].is_number? && rate_limit_split[1].is_number?
96
+ raise Exceptions::RookInvalidRateLimitConfiguration, config
97
+ end
98
+
99
+ window_quota = rate_limit_split[0].to_i
100
+ window_size = rate_limit_split[1].to_i
101
+ end
79
102
 
80
103
  window_quota_ns = Utils.milliseconds_to_nanoseconds window_quota
81
104
  window_size_ns = Utils.milliseconds_to_nanoseconds window_size
105
+ rate_limit_modifier = modifier_config.to_i || 5
82
106
 
83
- AugRateLimiter.new window_quota_ns, window_size_ns, rate_limit_modifier
107
+ [window_quota_ns, window_size_ns, rate_limit_modifier]
84
108
  end
85
109
  end
86
110
  end
@@ -8,51 +8,50 @@ module Rookout
8
8
  @quota = quota
9
9
  @has_quota = !@quota.nil? && (@quota > 0)
10
10
  @window_size = window_size
11
- @active_weight = quota / active_limit
11
+ if active_limit > 0
12
+ @active_weight = quota / active_limit
13
+ else
14
+ @active_weight = 0
15
+ end
12
16
 
13
17
  @mutex = Mutex.new
14
18
  @active_count = 0
15
19
  @windows = {}
16
20
  end
17
21
 
18
- def with_limit start_time = nil
19
- active = false
20
- start_time ||= Time.now
21
-
22
- # If quota, verify it
23
- if @has_quota
24
- # Get current time
25
- now_ns = Utils.time_to_nanoseconds start_time
26
-
27
- # Calculate window keys
28
- current_window_key, prev_window_key = timestamp_to_window_keys now_ns
29
-
30
- @mutex.synchronize do
31
- # Clean old windows
32
- cleanup now_ns
33
- # Increase active count
34
- @active_count += 1
35
- active = true
36
-
37
- # If exceeding quota
38
- if current_usage(now_ns, current_window_key, prev_window_key) > @quota
39
- warning = Processor::RookError.new Exceptions::RookRuleRateLimited.new
40
- UserWarnings.notify_warning warning
41
- return
42
- end
22
+ def before_run start_time
23
+ # If no quota, we can safely exit
24
+ unless @has_quota
25
+ return true
26
+ end
27
+ now_ns = Utils.time_to_nanoseconds start_time
28
+ current_window_key, prev_window_key = timestamp_to_window_keys now_ns
29
+
30
+ @mutex.synchronize do
31
+ # Clean old windows
32
+ cleanup now_ns
33
+ usage = current_usage now_ns, current_window_key, prev_window_key
34
+ @active_count += 1
35
+
36
+ # If exceeding quota
37
+ if usage > @quota
38
+ warning = Processor::RookError.new Exceptions::RookRuleRateLimited.new
39
+ UserWarnings.notify_warning warning
40
+ return false
43
41
  end
42
+
43
+ return true
44
44
  end
45
+ end
45
46
 
46
- begin
47
- yield
48
- ensure
49
- if @has_quota
50
- @mutex.synchronize { record_usage current_window_key, Utils.time_to_nanoseconds(Time.now) - now_ns }
51
- end
47
+ def after_run start_time
48
+ if @has_quota
49
+ now_ns = Utils.time_to_nanoseconds start_time
50
+ current_window_key, = timestamp_to_window_keys now_ns
51
+ @mutex.synchronize { record_usage current_window_key, Utils.time_to_nanoseconds(Time.now) - now_ns }
52
52
  end
53
- ensure
54
53
  # Reduce active count
55
- @mutex.synchronize { @active_count -= 1 } if active
54
+ @mutex.synchronize { @active_count -= 1 }
56
55
  end
57
56
 
58
57
  private
@@ -0,0 +1,31 @@
1
+ module Rookout
2
+ module Augs
3
+ class LimitsManager
4
+ def initialize limiters
5
+ @limiters = limiters
6
+ end
7
+
8
+ def with_limit start_time = nil
9
+ start_time ||= Time.now
10
+ can_execute = true
11
+ after_execute = []
12
+
13
+ @limiters.each do |limiter|
14
+ if limiter.before_run start_time
15
+ after_execute.append -> { limiter.after_run start_time }
16
+ else
17
+ can_execute = false
18
+ end
19
+ end
20
+
21
+ if can_execute
22
+ yield
23
+ end
24
+ ensure
25
+ unless after_execute.nil?
26
+ after_execute.each(&:call)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- COMMIT = "d0495f7919f4fa023c9192c095b24bcdfbf4c825".freeze
2
+ COMMIT = "b34115d35e36dcb568599cc5279fc7e934619ef5".freeze
3
3
  end
@@ -76,8 +76,16 @@ module Rookout
76
76
 
77
77
  Rookout::Config.true_values = ["y", "Y", "yes", "Yes", "YES", "true", "True", "TRUE", "1"]
78
78
 
79
+ attr_accessor :global_rate_limit
80
+
81
+ Rookout::Config.global_rate_limit = nil
79
82
 
80
83
  def update_config configuration
84
+ update_var2_config configuration
85
+ update_global_rate_limit_config configuration
86
+ end
87
+
88
+ def update_var2_config configuration
81
89
  is_config_proto2 = configuration["RUBY_PROTOBUF_VERSION_2"]
82
90
  return if is_config_proto2.nil?
83
91
  is_env_proto2 = ENV["ROOKOUT_Protobuf_Version2"]
@@ -89,6 +97,18 @@ module Rookout
89
97
  end
90
98
  Logger.instance.info "Updating ROOKOUT_Protobuf_Version2 value to: #{@protobuf_version2}"
91
99
  end
100
+
101
+ def update_global_rate_limit_config configuration
102
+ global_rate_limit = ENV["ROOKOUT_GLOBAL_RATE_LIMIT"]
103
+ if global_rate_limit.nil?
104
+ global_rate_limit = configuration["RUBY_GLOBAL_RATE_LIMIT"]
105
+ end
106
+
107
+ return if global_rate_limit.nil?
108
+
109
+ @global_rate_limit = global_rate_limit
110
+ Logger.instance.info "Updating global rate limit to: #{global_rate_limit}"
111
+ end
92
112
  end
93
113
  end
94
114
  end
@@ -214,6 +214,15 @@ module Rookout
214
214
  end
215
215
  end
216
216
 
217
+ class RookInvalidRateLimitConfiguration < ToolException
218
+ def initialize config
219
+ super "Invalid rate limit configuration: #{config}",
220
+ {
221
+ "rate_limit_config" => config
222
+ }
223
+ end
224
+ end
225
+
217
226
  class RookUnsupportedLiveLogger < ToolException
218
227
  def initialize
219
228
  super "Live Logger is not supported. Try using Rookout Live Debugger instead."
@@ -0,0 +1,22 @@
1
+ require "set"
2
+ module Rookout
3
+ class Sanitizer
4
+ @@blacklisted_properties = Set["labels", "ROOKOUT_LABELS"]
5
+
6
+ def self.sanitize_object! obj
7
+ obj.each_key do |key|
8
+ if obj[key].is_a?(String) && !@@blacklisted_properties.include?(key.to_s)
9
+ obj[key] = obj[key].strip
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.sanitize_properties!
15
+ ENV.each do |key, val|
16
+ if key.start_with?("ROOKOUT_") && !@@blacklisted_properties.include?(key.to_s)
17
+ ENV[key] = val.strip
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/rookout/utils.rb CHANGED
@@ -18,3 +18,9 @@ module Utils
18
18
  ((10**9) * secs) + nsecs
19
19
  end
20
20
  end
21
+
22
+ class String
23
+ def is_number?
24
+ to_f.to_s == self || to_i.to_s == self
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- VERSION = "0.1.38".freeze
2
+ VERSION = "0.1.39".freeze
3
3
  end
data/lib/rookout.rb CHANGED
@@ -2,6 +2,10 @@ module Rookout
2
2
  module_function
3
3
 
4
4
  def start options = {}
5
+ require_relative "rookout/sanitizer"
6
+ Sanitizer.sanitize_object! options
7
+ Sanitizer.sanitize_properties!
8
+
5
9
  require_relative "rookout/interface"
6
10
  Interface.instance.start options
7
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rookout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.38
4
+ version: 0.1.39
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liran Haimovitch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-23 00:00:00.000000000 Z
11
+ date: 2022-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: binding_of_caller
@@ -225,6 +225,7 @@ files:
225
225
  - lib/rookout/augs/aug_rate_limiter.rb
226
226
  - lib/rookout/augs/augs_manager.rb
227
227
  - lib/rookout/augs/conditions/condition.rb
228
+ - lib/rookout/augs/limits_manager.rb
228
229
  - lib/rookout/augs/locations/location.rb
229
230
  - lib/rookout/augs/locations/location_exception_handler.rb
230
231
  - lib/rookout/augs/locations/location_file_line.rb
@@ -273,6 +274,7 @@ files:
273
274
  - lib/rookout/protobuf/variant2_pb.rb
274
275
  - lib/rookout/protobuf/variant_pb.rb
275
276
  - lib/rookout/rookout_singleton.rb
277
+ - lib/rookout/sanitizer.rb
276
278
  - lib/rookout/services/position.rb
277
279
  - lib/rookout/services/tracer.rb
278
280
  - lib/rookout/trigger_services.rb