neetodeploy-autoscale 2.1.3 → 2.1.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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cdd8f665987aa730bfca4343fea2b9ae6f93bc5a4d6dcbc4152a7fb879165703
|
|
4
|
+
data.tar.gz: e0390da1428e2fa58547fc8045b7c769c824c502e37db945732833f2d3beb2b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a7e6a766486c6785ff2f53d7f0759bfaa1738b416c0f679df970ad2bcee1de9a1b1e97f0fedc61a6f94625ef30d14f7fdf5081eae0cb37bf1005a85b057bb34e
|
|
7
|
+
data.tar.gz: 2d843f184f0f3ba6acf8f0823e04860ded3c9e76fe6a1d512592e154507890c66021283a2087775387cdb153511412f3382fa0d0f83a47e124307616f1a898bf
|
|
@@ -1,29 +1,69 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "singleton"
|
|
4
|
+
require "neetodeploy/autoscale/logger"
|
|
4
5
|
|
|
5
6
|
module Neetodeploy
|
|
6
7
|
module Rails
|
|
7
8
|
class MetricsStore
|
|
8
9
|
include Singleton
|
|
9
10
|
|
|
11
|
+
# Use sliding window: keep last 2 minutes of data (120 seconds)
|
|
12
|
+
# At 2s reporting interval, this gives us ~60 samples per window
|
|
13
|
+
# This ensures percentiles work correctly even with low traffic
|
|
14
|
+
WINDOW_SIZE_SECONDS = 120
|
|
15
|
+
MAX_SAMPLES = 1000 # Safety limit to prevent memory bloat
|
|
16
|
+
|
|
10
17
|
attr_reader :metrics
|
|
11
18
|
|
|
12
19
|
def initialize
|
|
13
|
-
@metrics = []
|
|
20
|
+
@metrics = [] # Array of {time: timestamp, value: queue_time}
|
|
14
21
|
@mutex = Mutex.new
|
|
15
22
|
end
|
|
16
23
|
|
|
17
24
|
def push(queue_time)
|
|
18
25
|
@mutex.synchronize do
|
|
19
|
-
|
|
26
|
+
now = Time.now.to_f
|
|
27
|
+
@metrics << { time: now, value: queue_time }
|
|
28
|
+
|
|
29
|
+
# Remove old data outside window
|
|
30
|
+
cutoff = now - WINDOW_SIZE_SECONDS
|
|
31
|
+
@metrics.reject! { |m| m[:time] < cutoff }
|
|
32
|
+
|
|
33
|
+
# Safety limit: keep only most recent samples
|
|
34
|
+
if @metrics.size > MAX_SAMPLES
|
|
35
|
+
@metrics = @metrics.last(MAX_SAMPLES)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Log high queue times to help debug
|
|
39
|
+
if queue_time > 500
|
|
40
|
+
NeetoDeploy::Logger.logger.debug("MetricsStore: Pushed high queue_time=#{queue_time}ms (total in window: #{@metrics.size})")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Get recent samples from the sliding window (last N seconds)
|
|
46
|
+
def get_recent(seconds = WINDOW_SIZE_SECONDS)
|
|
47
|
+
@mutex.synchronize do
|
|
48
|
+
cutoff = Time.now.to_f - seconds
|
|
49
|
+
@metrics.select { |m| m[:time] >= cutoff }.map { |m| m[:value] }
|
|
20
50
|
end
|
|
21
51
|
end
|
|
22
52
|
|
|
53
|
+
# Flush: return all values in window, but DON'T clear (sliding window)
|
|
54
|
+
# This allows high values to persist across multiple reporting cycles
|
|
23
55
|
def flush
|
|
24
56
|
@mutex.synchronize do
|
|
25
|
-
|
|
26
|
-
|
|
57
|
+
# Clean up old data first
|
|
58
|
+
cutoff = Time.now.to_f - WINDOW_SIZE_SECONDS
|
|
59
|
+
@metrics.reject! { |m| m[:time] < cutoff }
|
|
60
|
+
|
|
61
|
+
result = @metrics.map { |m| m[:value] }
|
|
62
|
+
size = result.size
|
|
63
|
+
max_val = result.max if result.any?
|
|
64
|
+
NeetoDeploy::Logger.logger.debug("MetricsStore: Reporting from sliding window: #{size} values, max=#{max_val}ms") if result.any?
|
|
65
|
+
|
|
66
|
+
# Return values but keep them in the window for next cycle
|
|
27
67
|
result
|
|
28
68
|
end
|
|
29
69
|
end
|