judoscale-ruby 1.11.0 → 1.12.0

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: 92983f008bba242830346f573d60a9c7302c794cac38afbc0e78b359e4dd09e2
4
- data.tar.gz: 0c7971f58dab5fa1c17b43e14f25db639d5d81b2b0b2dc60e123e6951f0f645c
3
+ metadata.gz: b13782a2f01364bfe80c362bd11233f13b8cd4379a9621e6659d7f0f9ad27064
4
+ data.tar.gz: a9a720064114643c543cbfe440656c727fa5992af8f3eab73975ce13eeb79250
5
5
  SHA512:
6
- metadata.gz: f5452b651fe1582de5c6ae1c96f78738b30d2090635df3701a1e8d987f19ac0c6d9cb6a408cafcea62e0208616a5a11680919cb42695ef01023887980a4fa71c
7
- data.tar.gz: c63a089e0f391605166f7c65b2b0afd457bb05fde10a7c9cd1a1cf67641f67721f5a08f5005c38b8057ac4a7877738917506b2e724ff40a728263613f70f6888
6
+ metadata.gz: 4faf24acdbdfd11067b9591488ba6508f244ba50e79e25bf1e927193472051554694c6189c965bc5f8a28de1733aee0c2ae08c989544463cc8ab6f492e734aa6
7
+ data.tar.gz: a2178ef9d030c007ef4380216a93a660bbfe638cf1ea7114b6b478dca779710e2fbfd2174cf455fc8df18f43a2035772a6504d4438645dc2ea5c91e418b0a49d
@@ -50,11 +50,11 @@ module Judoscale
50
50
  Thread.current.thread_variable_set(:fork_safe, true)
51
51
 
52
52
  loop do
53
- run_metrics_collection(config, metrics_collectors)
54
-
55
53
  # Stagger reporting to spread out reports from many processes
56
54
  multiplier = 1 - (rand / 4) # between 0.75 and 1.0
57
55
  sleep config.report_interval_seconds * multiplier
56
+
57
+ run_metrics_collection(config, metrics_collectors)
58
58
  end
59
59
  end
60
60
  end
@@ -4,6 +4,7 @@ require "judoscale/metrics_store"
4
4
  require "judoscale/reporter"
5
5
  require "judoscale/logger"
6
6
  require "judoscale/request_metrics"
7
+ require "judoscale/utilization_tracker"
7
8
 
8
9
  module Judoscale
9
10
  class RequestMiddleware
@@ -14,6 +15,10 @@ module Judoscale
14
15
  end
15
16
 
16
17
  def call(env)
18
+ tracker = UtilizationTracker.instance
19
+ tracker.start!
20
+ tracker.incr
21
+
17
22
  request_metrics = RequestMetrics.new(env)
18
23
  store = MetricsStore.instance
19
24
  time = Time.now.utc
@@ -42,6 +47,8 @@ module Judoscale
42
47
  store.push :at, app_time, time
43
48
 
44
49
  response
50
+ ensure
51
+ tracker.decr
45
52
  end
46
53
  end
47
54
  end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ module Judoscale
6
+ class UtilizationTracker
7
+ include Singleton
8
+
9
+ def initialize
10
+ @mutex = Mutex.new
11
+ @active_request_counter = 0
12
+ @started = false
13
+ end
14
+
15
+ def start!
16
+ @mutex.synchronize do
17
+ unless started?
18
+ @started = true
19
+ init_idle_report_cycle!
20
+ end
21
+ end
22
+ end
23
+
24
+ def started?
25
+ @started
26
+ end
27
+
28
+ def incr
29
+ @mutex.synchronize do
30
+ if @active_request_counter == 0 && @idle_started_at
31
+ # We were idle and now we're not - add to total idle time
32
+ @total_idle_time += get_current_time - @idle_started_at
33
+ @idle_started_at = nil
34
+ end
35
+
36
+ @active_request_counter += 1
37
+ end
38
+ end
39
+
40
+ def decr
41
+ @mutex.synchronize do
42
+ @active_request_counter -= 1
43
+
44
+ if @active_request_counter == 0
45
+ # We're now idle - start tracking idle time
46
+ @idle_started_at = get_current_time
47
+ end
48
+ end
49
+ end
50
+
51
+ def utilization_pct(reset: true)
52
+ @mutex.synchronize do
53
+ current_time = get_current_time
54
+ idle_ratio = get_idle_ratio(current_time: current_time)
55
+
56
+ reset_idle_report_cycle!(current_time: current_time) if reset
57
+
58
+ ((1.0 - idle_ratio) * 100.0).to_i
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def get_current_time
65
+ Process.clock_gettime Process::CLOCK_MONOTONIC
66
+ end
67
+
68
+ def init_idle_report_cycle!
69
+ current_time = get_current_time
70
+ @idle_started_at = current_time
71
+ reset_idle_report_cycle! current_time: current_time
72
+ end
73
+
74
+ def reset_idle_report_cycle!(current_time:)
75
+ @total_idle_time = 0.0
76
+ @report_cycle_started_at = current_time
77
+ end
78
+
79
+ def get_idle_ratio(current_time: get_current_time)
80
+ return 0.0 if @report_cycle_started_at.nil?
81
+
82
+ total_report_cycle_time = current_time - @report_cycle_started_at
83
+
84
+ return 0.0 if total_report_cycle_time <= 0
85
+
86
+ # Capture remaining idle time
87
+ if @idle_started_at
88
+ @total_idle_time += current_time - @idle_started_at
89
+ @idle_started_at = current_time
90
+ end
91
+
92
+ @total_idle_time / total_report_cycle_time
93
+ end
94
+ end
95
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Judoscale
4
- VERSION = "1.11.0"
4
+ VERSION = "1.12.0"
5
5
  end
@@ -2,11 +2,20 @@
2
2
 
3
3
  require "judoscale/metrics_collector"
4
4
  require "judoscale/metrics_store"
5
+ require "judoscale/utilization_tracker"
5
6
 
6
7
  module Judoscale
7
8
  class WebMetricsCollector < MetricsCollector
8
9
  def collect
9
- MetricsStore.instance.flush
10
+ metrics = MetricsStore.instance.flush
11
+
12
+ # Only report utilization if a request has already started the tracker
13
+ if UtilizationTracker.instance.started?
14
+ utilization_pct = UtilizationTracker.instance.utilization_pct
15
+ metrics.push Metric.new(:up, utilization_pct, Time.now)
16
+ end
17
+
18
+ metrics
10
19
  end
11
20
  end
12
21
  end
metadata CHANGED
@@ -1,18 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: judoscale-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam McCrea
8
8
  - Carlos Antonio da Silva
9
9
  - Jon Sullivan
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2025-04-28 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
14
13
  dependencies: []
15
- description:
16
14
  email:
17
15
  - hello@judoscale.com
18
16
  executables: []
@@ -32,6 +30,7 @@ files:
32
30
  - lib/judoscale/reporter.rb
33
31
  - lib/judoscale/request_metrics.rb
34
32
  - lib/judoscale/request_middleware.rb
33
+ - lib/judoscale/utilization_tracker.rb
35
34
  - lib/judoscale/version.rb
36
35
  - lib/judoscale/web_metrics_collector.rb
37
36
  homepage: https://judoscale.com
@@ -43,7 +42,6 @@ metadata:
43
42
  documentation_uri: https://judoscale.com/docs
44
43
  changelog_uri: https://github.com/judoscale/judoscale-ruby/blob/main/CHANGELOG.md
45
44
  source_code_uri: https://github.com/judoscale/judoscale-ruby
46
- post_install_message:
47
45
  rdoc_options: []
48
46
  require_paths:
49
47
  - lib
@@ -58,8 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
56
  - !ruby/object:Gem::Version
59
57
  version: '0'
60
58
  requirements: []
61
- rubygems_version: 3.5.22
62
- signing_key:
59
+ rubygems_version: 3.6.9
63
60
  specification_version: 4
64
61
  summary: Autoscaling for Ruby.
65
62
  test_files: []