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.
This commit is contained in:
songtianlun 2025-02-17 15:07:34 +08:00
parent f79299d707
commit 888dc7f22d
3 changed files with 30 additions and 5 deletions

View File

@ -65,6 +65,8 @@ gem "image_processing", "~> 1.13"
# gem "ruby-vips", "~> 2.2"
gem "mini_magick", "~> 4.13.2"
gem "redis", "~> 5.3"
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"

View File

@ -365,6 +365,8 @@ GEM
i18n
rdoc (6.11.0)
psych (>= 4.0.0)
redis (5.3.0)
redis-client (>= 0.22.0)
redis-client (0.23.2)
connection_pool
regexp_parser (2.10.0)
@ -541,6 +543,7 @@ DEPENDENCIES
puma (>= 5.0)
rack-mini-profiler (~> 3.3)
rails (~> 8.0.1)
redis (~> 5.3)
rubocop-rails-omakase
ruby-openai (~> 7.3)
selenium-webdriver

View File

@ -1,7 +1,27 @@
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)
@ -12,7 +32,7 @@ class RefreshSitemapWorker
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)),
@ -20,7 +40,7 @@ class RefreshSitemapWorker
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/"
@ -43,9 +63,9 @@ class RefreshSitemapWorker
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')}"
} ]
loc: url_for(art.image),
title: "#{art.city.name} Weather Art - #{art.weather_date.strftime('%B %d, %Y')}"
} ]
end
end
end