# frozen_string_literal: true module Streams class AutoscalerJob include Sidekiq::Job sidekiq_options retry: 1, queue: "default" INTERVAL_SECS = ENV.fetch("STREAM_AUTOSCALE_INTERVAL_SECS", "60").to_i REDIS_CHAIN_KEY = "streams:autoscaler:chain" KICK_DEBOUNCE_KEY = "streams:autoscaler:kick" KICK_DEBOUNCE_SECS = ENV.fetch("STREAM_AUTOSCALE_KICK_DEBOUNCE_SECS", "5").to_i def self.ensure_chain return unless redis return if redis.get(REDIS_CHAIN_KEY) redis.set(REDIS_CHAIN_KEY, "1", ex: INTERVAL_SECS * 2) perform_in(INTERVAL_SECS) end # Kick immediato (es. NoCapacity / soft-free bassi). Debounce anti-flood Sidekiq. def self.kick! return false unless Streams::Autoscaler.enabled? return false unless redis return false unless redis.set(KICK_DEBOUNCE_KEY, "1", nx: true, ex: KICK_DEBOUNCE_SECS) perform_async true end def self.redis @redis ||= Redis.new(url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0")) rescue Redis::CannotConnectError nil end def perform Streams::Autoscaler.reconcile! ensure self.class.redis&.set(REDIS_CHAIN_KEY, "1", ex: INTERVAL_SECS * 2) self.class.perform_in(INTERVAL_SECS) end end end