Files
redux-scraper/app/lib/enqueue_job_base.rb
2025-09-10 16:30:51 +00:00

89 lines
2.2 KiB
Ruby

# typed: strict
class EnqueueJobBase < Tasks::InterruptableTask
include HasColorLogger
abstract!
class DateHelper
extend ActionView::Helpers::DateHelper
end
sig do
params(perform_max: T.nilable(Integer), log_sink: T.any(IO, StringIO)).void
end
def initialize(perform_max: nil, log_sink: $stderr)
@total_performed = T.let(0, Integer)
@perform_max = T.let(perform_max, T.nilable(Integer))
@inferred_queue_size = T.let(0, Integer)
super(log_sink:)
end
sig { returns(Integer) }
def high_water_mark
100
end
sig { returns(Integer) }
def low_water_mark
50
end
sig { returns(ActiveSupport::Duration) }
def delay_time
10.seconds
end
sig { override.void }
def run_impl
@inferred_queue_size = queue_size
logger.info(
"initial queue size is #{@inferred_queue_size}, starting enqueuing",
)
start_enqueuing
end
sig { abstract.void }
def start_enqueuing
end
sig { params(always_recheck: T::Boolean, block: T.proc.void).void }
def enqueue(always_recheck: false, &block)
# if we're under the high water mark, we can just enqueue and return
# so we get called again as soon as possible
if @inferred_queue_size < high_water_mark
# logger.info("queue is at #{@inferred_queue_size}, enqueuing")
else
# if we're over the high water mark, we need to wait for the queue to drop
# so we don't enqueue too many jobs at once
while @inferred_queue_size > low_water_mark
logger.info(
"waiting for queue to drop to #{low_water_mark} (currently #{@inferred_queue_size}, total performed #{@total_performed})",
)
sleep delay_time.in_seconds
@inferred_queue_size = queue_size
end
end
block.call
if always_recheck
@inferred_queue_size = queue_size
else
@inferred_queue_size += 1
end
@total_performed += 1
end
sig { abstract.returns(Integer) }
def queue_size
end
sig do
params(time: T.nilable(T.any(ActiveSupport::TimeWithZone, Time))).returns(
String,
)
end
def time_ago_in_words(time)
return "never" if time.nil?
"#{DateHelper.time_ago_in_words(time)} ago"
end
end