today_ai_weather/app/workers/refresh_sitemap_worker.rb
songtianlun 888dc7f22d feat: add Redis integration for sitemap refresh
- Include Redis gem in the Gemfile and update Gemfile.lock
- Implement locking mechanism in the RefreshSitemapWorker to prevent concurrent executions
- Use Redis to manage distributed locks for the sitemap generation process

This change introduces Redis for managing access controls in the sitemap
refresh workflow. It prevents multiple simultaneous jobs from running,
improving stability and performance when generating sitemaps.
2025-02-17 15:07:34 +08:00

79 lines
3.1 KiB
Ruby

class RefreshSitemapWorker
include Sidekiq::Worker
require "redis"
def perform
lock_key = "refresh_sitemap_lock"
lock_ttl = 60 # 锁的生存时间,单位为秒
redis = Redis.new(url: ENV.fetch("REDIS_URL", "redis://localhost:6379/1"))
if redis.set(lock_key, Time.current.to_s, nx: true, ex: lock_ttl)
begin
generate_sitemap
ensure
redis.del(lock_key)
end
else
Rails.logger.info "Sitemap refresh is already in progress"
end
end
private
def generate_sitemap
host = Rails.env.production? ? "https://todayaiweather.com" : "http://127.0.0.1:3000"
Rails.application.routes.default_url_options[:host] = host
SitemapGenerator::Sitemap.default_host = ENV.fetch("RAILS_SITEMAP_DEFAULT_HOST", host)
if Rails.env.production?
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
ENV.fetch("AWS_BUCKET", Rails.application.credentials.dig(:aws, :bucket)),
aws_access_key_id: ENV.fetch("AWS_ACCESS_KEY_ID", Rails.application.credentials.dig(:aws, :access_key_id)),
aws_secret_access_key: ENV.fetch("AWS_SECRET_ACCESS_KEY_ID", Rails.application.credentials.dig(:aws, :secret_access_key)),
aws_region: ENV.fetch("AWS_REGION", "wnam"),
endpoint: ENV.fetch("AWS_ENDPOINT", Rails.application.credentials.dig(:aws, :endpoint)),
)
else
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
ENV.fetch("AWS_DEV_BUCKET", Rails.application.credentials.dig(:aws_dev, :bucket)),
aws_access_key_id: ENV.fetch("AWS_DEV_ACCESS_KEY_ID", Rails.application.credentials.dig(:aws_dev, :access_key_id)),
aws_secret_access_key: ENV.fetch("AWS_DEV_SECRET_ACCESS_KEY_ID", Rails.application.credentials.dig(:aws_dev, :secret_access_key)),
aws_region: ENV.fetch("AWS_DEV_REGION", "wnam"),
endpoint: ENV.fetch("AWS_DEV_ENDPOINT", Rails.application.credentials.dig(:aws_dev, :endpoint)),
)
end
SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/"
SitemapGenerator::Sitemap.create do
add root_path, changefreq: "daily", priority: 1.0
add cities_path, changefreq: "daily", priority: 0.9
add arts_path, changefreq: "daily", priority: 0.9
City.find_each do |city|
add city_path(city),
changefreq: "daily",
priority: 0.8,
lastmod: city.updated_at
end
WeatherArt.includes(:city).find_each do |art|
if art.image.attached?
add city_weather_art_path(art.city, art),
changefreq: "daily",
priority: 0.7,
lastmod: art.updated_at,
images: [ {
loc: url_for(art.image),
title: "#{art.city.name} Weather Art - #{art.weather_date.strftime('%B %d, %Y')}"
} ]
end
end
end
# SitemapGenerator::Sitemap.ping_search_engines if Rails.env.production?
Rails.logger.info "Sitemap has been generated and uploaded to S3 successfully"
rescue => e
Rails.logger.error "Error refreshing sitemap: #{e.message}"
end
end