50 lines
1.2 KiB
Ruby
50 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Scheduler::BoostsScheduler
|
|
include Sidekiq::Worker
|
|
include Redisable
|
|
|
|
sidekiq_options unique: :until_executed, retry: 0
|
|
|
|
def perform
|
|
process_queued_boosts!
|
|
end
|
|
|
|
private
|
|
|
|
def process_queued_boosts!
|
|
queued_accounts.find_each do |account|
|
|
next if redis.exists("queued_boost:#{account.id}") || account&.user.nil?
|
|
|
|
q = next_boost(account.id, account.user.boost_random?)
|
|
next if q.empty?
|
|
|
|
from_interval = account.user.boost_interval_from
|
|
to_interval = account.user.boost_interval_to
|
|
|
|
if from_interval > to_interval
|
|
from_interval, to_interval = [to_interval, from_interval]
|
|
end
|
|
|
|
interval = rand(from_interval .. to_interval).minutes
|
|
|
|
redis.setex("queued_boost:#{account.id}", interval, 1)
|
|
ReblogStatusWorker.perform_async(account.id, q.first.status_id, distribute: true)
|
|
q.destroy_all
|
|
end
|
|
end
|
|
|
|
def queued_accounts
|
|
Account.where(id: queued_account_ids)
|
|
end
|
|
|
|
def queued_account_ids
|
|
QueuedBoost.distinct.pluck(:account_id)
|
|
end
|
|
|
|
def next_boost(account_id, boost_random = false)
|
|
q = QueuedBoost.where(account_id: account_id)
|
|
(boost_random ? q.order(Arel.sql('RANDOM()')) : q.order(:id)).limit(1)
|
|
end
|
|
end
|