89 lines
2.2 KiB
Ruby
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
|