neetodeploy-autoscale 2.0.3 → 2.0.4

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: 85b4ae0e9d4ca64aa8defb71b1a48f95ddfc8dd6ead0c36da7718e102596e6bd
4
+ data.tar.gz: bbddecea047a1fe57852b6ccc50040e60d0617498d29dfd25b56780d37a8ba1d
5
5
  SHA512:
6
- metadata.gz: 77e3bb73219f39f717511e3b9f860daf6cbc610b26f656061312a54095c2d6d62e894c8a44027c35fff37948edcada469bf4bfc5a33ede5deec5917320a9a1e2
7
- data.tar.gz: f40763ca2219295b1a64c0f76addeeb8539493be1757bdec45ef7830f6379e1b741903ae5acc3894510a37d5dfd600103b25cabfabee2e960bf441332b7fd334
6
+ metadata.gz: e0cb2130f7a0453d1ddeef3e580ae4347bb1041ca7367839e3a54cb95c2dfd7ad60c7f8a11f14974f0ba4e4eebf0160ff7f3c8d92ec7bce3014badb924bad88e
7
+ data.tar.gz: d2974979d2cb668b1d36bee0e77dd1c0a1c7b680557faebcb560ce5b8d09e3fcd5f87f36366ae978daaa7840b86cb8c624372c313e8a1f14fdd010a9ed92d409
@@ -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 == true
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,82 @@ 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
40
+ metrics_store = MetricsStore.instance unless config.use_puma_queue_size?
37
41
  loop do
38
- run_metrics_collection(metrics_store)
42
+ if config.use_puma_queue_size?
43
+ run_puma_metrics_collection(config)
44
+ else
45
+ run_queue_time_collection(metrics_store, config)
46
+ end
39
47
  multiplier = 1 - (rand / 4)
40
48
  sleep config.report_interval_seconds * multiplier
41
49
  end
50
+ rescue StandardError => e
51
+ logger.error("Rails metrics collector thread terminated with error: #{e.message}")
52
+ logger.error(e.backtrace.join("\n")) if e.backtrace
53
+ ensure
54
+ if @pid == Process.pid && !@thread.nil?
55
+ logger.info("Restarting Rails metrics collector thread")
56
+ sleep(5)
57
+ start_thread_with_collector_loop
58
+ end
42
59
  end
43
60
  end
44
61
 
45
- def run_metrics_collection(metrics_store)
62
+ def run_queue_time_collection(metrics_store, config)
63
+ return if config.gem_disabled?
64
+
46
65
  data = metrics_store.flush
47
66
  return if data.empty?
48
67
 
49
68
  average_queue_time = data.sum / data.size
50
69
  Reporter.new(average_queue_time, "queue_time", "web").report
51
70
  end
71
+
72
+ def run_puma_metrics_collection(config)
73
+ return unless puma_available?
74
+ return if config.gem_disabled?
75
+
76
+ begin
77
+ queue_size = get_puma_queue_size
78
+ return if queue_size.nil?
79
+
80
+ Reporter.new(queue_size, "puma_queue_size", "web").report
81
+ rescue StandardError => e
82
+ logger.error("Error collecting Puma queue size metrics: #{e.message}")
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def puma_available?
89
+ defined?(::Puma) && ::Puma.respond_to?(:stats)
90
+ end
91
+
92
+ def get_puma_queue_size
93
+ stats_json = ::Puma.stats
94
+ return nil if stats_json.nil? || stats_json.empty?
95
+
96
+ stats = JSON.parse(stats_json)
97
+
98
+ # For clustered mode (multiple workers)
99
+ if stats["worker_status"]
100
+ # Sum backlog from all workers
101
+ stats["worker_status"].sum do |worker|
102
+ worker.dig("last_status", "backlog") || 0
103
+ end
104
+ # For single mode
105
+ elsif stats["backlog"]
106
+ stats["backlog"]
107
+ else
108
+ nil
109
+ end
110
+ end
52
111
  end
53
112
  end
54
113
  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.4"
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.4
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