neetodeploy-autoscale 2.0.3 → 2.0.5

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: 27447ab3dd1a86114502dba20ac472fdbbc5de7c56e6d65bb9f4b5790c24a6cd
4
- data.tar.gz: 8124289ad97a7ea6742af785d5c6183e2f2238faa65c7fb38a1275fe58fdeafc
3
+ metadata.gz: 5c7265603142b311a9ff85c2bb44678261113c889ef554399132dd6f4d41931d
4
+ data.tar.gz: 6ab7a1fc5cb14f7b2c7ebb93fea67266cbe9c34b41abd4d3bcf2e4c7ecd41c0f
5
5
  SHA512:
6
- metadata.gz: 77e3bb73219f39f717511e3b9f860daf6cbc610b26f656061312a54095c2d6d62e894c8a44027c35fff37948edcada469bf4bfc5a33ede5deec5917320a9a1e2
7
- data.tar.gz: f40763ca2219295b1a64c0f76addeeb8539493be1757bdec45ef7830f6379e1b741903ae5acc3894510a37d5dfd600103b25cabfabee2e960bf441332b7fd334
6
+ metadata.gz: 628156b95ff204ecbc18ca301c318618d474495c506896859ecdd3f53c93dcda4a3e7bf18dc4c69d1d4eb5db2dfdb99dd49a9d051bc3f856d9d58559f30a4e89
7
+ data.tar.gz: ac9de8142aa4599e664c4637ff3738dcbeb9888ec67c98029e0d1dbf734e050d4943cc5a60a1cca67e70b37b6823dacbfa4c7137387de795b7e1c60c66261205
@@ -3,7 +3,7 @@ module Neetodeploy
3
3
  include Singleton
4
4
 
5
5
  attr_accessor :disable_auto_scale_gem, :disable_sidekiq_metrics, :app_name, :metrics_server_url,
6
- :metrics_server_auth_token, :report_interval_seconds
6
+ :metrics_server_auth_token, :report_interval_seconds, :use_puma_queue_size
7
7
 
8
8
  def initialize
9
9
  @disable_auto_scale_gem = ENV["DISABLE_NEETO_DEPLOY_AUTOSCALE"]
@@ -12,6 +12,7 @@ module Neetodeploy
12
12
  @metrics_server_url = "http://nd-queue-time-exporter-web-deployment:3000/metrics"
13
13
  @metrics_server_auth_token = "K0An3O3MSyEEMTCnRd1IHgGjdGQkzy"
14
14
  @report_interval_seconds = 10
15
+ @use_puma_queue_size = ENV["NEETODEPLOY_USE_PUMA_QUEUE_SIZE"] == "true"
15
16
  end
16
17
 
17
18
  def gem_disabled?
@@ -21,5 +22,9 @@ module Neetodeploy
21
22
  def sidekiq_metrics_disabled?
22
23
  disable_sidekiq_metrics == "true"
23
24
  end
25
+
26
+ def use_puma_queue_size?
27
+ use_puma_queue_size
28
+ end
24
29
  end
25
30
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "singleton"
4
- require "neetodeploy/autoscale/rails/metrics_store"
4
+ require "json"
5
5
  require "neetodeploy/autoscale/reporter"
6
6
  require "neetodeploy/autoscale/logger"
7
+ require "neetodeploy/autoscale/config"
8
+ require "neetodeploy/autoscale/rails/metrics_store"
7
9
 
8
10
  module Neetodeploy
9
11
  module Rails
@@ -16,7 +18,9 @@ module Neetodeploy
16
18
  end
17
19
 
18
20
  def start!
19
- logger.info("Starting background worker to collect metrics")
21
+ config = Config.instance
22
+ mode = config.use_puma_queue_size? ? "Puma queue size" : "response time"
23
+ logger.info("Starting background worker to collect #{mode} metrics")
20
24
  @pid = Process.pid
21
25
  start_thread_with_collector_loop
22
26
  end
@@ -28,27 +32,86 @@ module Neetodeploy
28
32
  end
29
33
 
30
34
  def running?
31
- @pid == Process.pid and @thread.alive?
35
+ @pid == Process.pid and @thread&.alive?
32
36
  end
33
37
 
34
38
  def start_thread_with_collector_loop(config = Config.instance)
35
39
  @thread = Thread.new do
36
- metrics_store = MetricsStore.instance
37
40
  loop do
38
- run_metrics_collection(metrics_store)
39
- multiplier = 1 - (rand / 4)
40
- sleep config.report_interval_seconds * multiplier
41
+ begin
42
+ metrics_store = MetricsStore.instance unless config.use_puma_queue_size?
43
+ loop do
44
+ if config.use_puma_queue_size?
45
+ run_puma_metrics_collection(config)
46
+ else
47
+ run_queue_time_collection(metrics_store, config)
48
+ end
49
+ multiplier = 1 - (rand / 4)
50
+ sleep config.report_interval_seconds * multiplier
51
+ end
52
+ rescue StandardError => e
53
+ logger.error("Rails metrics collector thread terminated with error: #{e.message}")
54
+ logger.error(e.backtrace.join("\n")) if e.backtrace
55
+
56
+ # Only restart if we're still the same process and thread should continue
57
+ break unless @pid == Process.pid && !@thread.nil?
58
+
59
+ logger.info("Restarting Rails metrics collector thread")
60
+ sleep(5)
61
+ end
41
62
  end
42
63
  end
43
64
  end
44
65
 
45
- def run_metrics_collection(metrics_store)
66
+ def run_queue_time_collection(metrics_store, config)
67
+ return if config.gem_disabled?
68
+
46
69
  data = metrics_store.flush
47
70
  return if data.empty?
48
71
 
49
72
  average_queue_time = data.sum / data.size
50
73
  Reporter.new(average_queue_time, "queue_time", "web").report
51
74
  end
75
+
76
+ def run_puma_metrics_collection(config)
77
+ return unless puma_available?
78
+ return if config.gem_disabled?
79
+
80
+ begin
81
+ queue_size = get_puma_queue_size
82
+ return if queue_size.nil?
83
+
84
+ Reporter.new(queue_size, "puma_queue_size", "web").report
85
+ rescue StandardError => e
86
+ logger.error("Error collecting Puma queue size metrics: #{e.message}")
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def puma_available?
93
+ defined?(::Puma) && ::Puma.respond_to?(:stats)
94
+ end
95
+
96
+ def get_puma_queue_size
97
+ stats_json = ::Puma.stats
98
+ return nil if stats_json.nil? || stats_json.empty?
99
+
100
+ stats = JSON.parse(stats_json)
101
+
102
+ # For clustered mode (multiple workers)
103
+ if stats["worker_status"]
104
+ # Sum backlog from all workers
105
+ stats["worker_status"].sum do |worker|
106
+ worker.dig("last_status", "backlog") || 0
107
+ end
108
+ # For single mode
109
+ elsif stats["backlog"]
110
+ stats["backlog"]
111
+ else
112
+ nil
113
+ end
114
+ end
52
115
  end
53
116
  end
54
117
  end
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "net/http"
4
- require "time"
5
3
  require "neetodeploy/autoscale/rails/metrics"
6
4
  require "neetodeploy/autoscale/rails/metrics_store"
7
5
  require "neetodeploy/autoscale/rails/metrics_collector"
6
+ require "neetodeploy/autoscale/config"
8
7
 
9
8
  module Neetodeploy
10
9
  module Rails
@@ -14,13 +13,18 @@ module Neetodeploy
14
13
  end
15
14
 
16
15
  def call(env)
17
- metrics = Metrics.new(env)
18
- queue_time = metrics.queue_time unless metrics.ignore?
16
+ config = Config.instance
19
17
  MetricsCollector.start
20
18
 
21
- if queue_time
22
- store = MetricsStore.instance
23
- store.push queue_time
19
+ # Only collect queue time per request if using the old response time method
20
+ unless config.use_puma_queue_size?
21
+ metrics = Metrics.new(env)
22
+ queue_time = metrics.queue_time unless metrics.ignore?
23
+
24
+ if queue_time
25
+ store = MetricsStore.instance
26
+ store.push queue_time
27
+ end
24
28
  end
25
29
 
26
30
  @app.call(env)
@@ -9,8 +9,8 @@ module Neetodeploy
9
9
  class Reporter
10
10
  include NeetoDeploy::Logger
11
11
 
12
- def initialize(queue_time, metric_name, process_type, queue_name = nil, config = Config.instance)
13
- @queue_time = queue_time.to_i
12
+ def initialize(metric_value, metric_name, process_type, queue_name = nil, config = Config.instance)
13
+ @metric_value = metric_value.to_i
14
14
  @config = config
15
15
  @metric_name = metric_name
16
16
  @queue_name = queue_name
@@ -21,7 +21,7 @@ module Neetodeploy
21
21
  params = common_params
22
22
  params[:queue_name] = @queue_name if @queue_name
23
23
  url = build_url(params)
24
- logger.info("Reporting average queue time for #{@process_type} dyno: #{@queue_time}")
24
+ logger.info("Reporting #{@metric_name} for #{@process_type} dyno: #{@metric_value}")
25
25
 
26
26
  post_request(url)
27
27
  end
@@ -31,7 +31,7 @@ module Neetodeploy
31
31
  def common_params
32
32
  {
33
33
  app_name: @config.app_name,
34
- queue_time: @queue_time,
34
+ queue_time: @metric_value, # Keep queue_time parameter name for backward compatibility with metrics server
35
35
  metric_name: @metric_name,
36
36
  process_type: @process_type
37
37
  }
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Neetodeploy
4
4
  module Autoscale
5
- VERSION = "2.0.3"
5
+ VERSION = "2.0.5"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neetodeploy-autoscale
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sreeram Venkitesh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-09-23 00:00:00.000000000 Z
11
+ date: 2025-11-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: For automatically scaling your Rails application based on network metrics
14
14
  email:
@@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
56
  - !ruby/object:Gem::Version
57
57
  version: '0'
58
58
  requirements: []
59
- rubygems_version: 3.4.1
59
+ rubygems_version: 3.5.16
60
60
  signing_key:
61
61
  specification_version: 4
62
62
  summary: neetoDeploy autoscaler gem