- 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.
79 lines
3.1 KiB
Ruby
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
|