2025-01-28 01:03:06 +08:00
|
|
|
class BatchGenerateWeatherArtsWorker
|
|
|
|
include Sidekiq::Worker
|
|
|
|
|
|
|
|
GENERATION_INTERVAL = 24.hours
|
|
|
|
MAX_DURATION = 50.minutes
|
|
|
|
SLEEP_DURATION = 120.seconds
|
2025-01-22 16:50:00 +08:00
|
|
|
|
|
|
|
def perform(*args)
|
|
|
|
start_time = Time.current
|
|
|
|
|
|
|
|
cities_to_process = get_eligible_cities
|
|
|
|
|
|
|
|
cities_to_process.each do |city|
|
2025-01-28 01:03:06 +08:00
|
|
|
break if Time.current - start_time > MAX_DURATION
|
|
|
|
Rails.logger.info "Generating weather art for #{city.name}"
|
2025-01-22 16:50:00 +08:00
|
|
|
|
2025-01-28 01:03:06 +08:00
|
|
|
GenerateWeatherArtWorker.perform_async(city.id)
|
|
|
|
sleep SLEEP_DURATION
|
2025-01-22 16:50:00 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def get_eligible_cities
|
2025-01-28 01:03:06 +08:00
|
|
|
cutoff_time = Time.current - GENERATION_INTERVAL
|
|
|
|
|
2025-01-22 16:50:00 +08:00
|
|
|
City.active
|
2025-01-28 01:03:06 +08:00
|
|
|
.joins("LEFT JOIN (
|
|
|
|
SELECT city_id, MAX(created_at) as last_generation_time
|
|
|
|
FROM weather_arts
|
|
|
|
GROUP BY city_id
|
|
|
|
) latest_arts ON cities.id = latest_arts.city_id")
|
|
|
|
.where("latest_arts.last_generation_time IS NULL OR latest_arts.last_generation_time < ?", cutoff_time)
|
|
|
|
.order(:priority)
|
2025-01-22 16:50:00 +08:00
|
|
|
end
|
|
|
|
end
|