Files
baffle-hub/app/services/hub_load.rb

79 lines
2.2 KiB
Ruby

# frozen_string_literal: true
# HubLoad - Calculates dynamic event sampling rate based on system load
#
# This service monitors SolidQueue depth and adjusts sampling rates to prevent
# the Hub from being overwhelmed while ensuring critical events are always captured.
class HubLoad
# Queue depth thresholds
THRESHOLDS = {
normal: 0..1_000, # 100% sampling
moderate: 1_001..5_000, # 50% sampling
high: 5_001..10_000, # 20% sampling
critical: 10_001..Float::INFINITY # 5% sampling
}.freeze
SAMPLING_RATES = {
normal: { allowed: 1.0, blocked: 1.0, rate_limited: 1.0 },
moderate: { allowed: 0.5, blocked: 1.0, rate_limited: 1.0 },
high: { allowed: 0.2, blocked: 1.0, rate_limited: 1.0 },
critical: { allowed: 0.05, blocked: 1.0, rate_limited: 1.0 }
}.freeze
# Get current sampling configuration based on load
def self.current_sampling
load_level = calculate_load_level
rates = SAMPLING_RATES[load_level]
{
allowed_requests: rates[:allowed],
blocked_requests: rates[:blocked],
rate_limited_requests: rates[:rate_limited],
effective_until: next_sync_time,
load_level: load_level,
queue_depth: queue_depth
}
end
# Calculate when sampling should be rechecked (next agent sync)
def self.next_sync_time
10.seconds.from_now.iso8601(3)
end
# Get current queue depth
def self.queue_depth
# SolidQueue stores jobs in the jobs table
# Count pending/running jobs only
SolidQueue::Job.where(finished_at: nil).count
rescue StandardError => e
Rails.logger.error "Failed to get queue depth: #{e.message}"
0
end
# Determine load level based on queue depth
def self.calculate_load_level
depth = queue_depth
THRESHOLDS.each do |level, range|
return level if range.cover?(depth)
end
:critical # Fallback
end
# Check if hub is under heavy load
def self.overloaded?
calculate_load_level.in?([:high, :critical])
end
# Get load statistics for monitoring
def self.stats
{
queue_depth: queue_depth,
load_level: calculate_load_level,
sampling_rates: SAMPLING_RATES[calculate_load_level],
overloaded: overloaded?
}
end
end