From b195956ecb07e9a3e47123a5bad95a664b257ffc Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Wed, 28 May 2025 14:34:37 +0200 Subject: [PATCH] Encapsulate redis key usage (#34840) --- app/models/home_feed.rb | 8 ++++++ app/models/user.rb | 6 +++- app/services/follow_service.rb | 2 +- app/services/precompute_feed_service.rb | 2 +- app/workers/merge_worker.rb | 2 +- spec/models/home_feed_spec.rb | 38 +++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 4 deletions(-) diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb index d6ebb5fa6b..81730ac98f 100644 --- a/app/models/home_feed.rb +++ b/app/models/home_feed.rb @@ -9,4 +9,12 @@ class HomeFeed < Feed def regenerating? redis.exists?("account:#{@account.id}:regeneration") end + + def regeneration_in_progress! + redis.set("account:#{@account.id}:regeneration", true, nx: true, ex: 1.day.seconds) + end + + def regeneration_finished! + redis.del("account:#{@account.id}:regeneration") + end end diff --git a/app/models/user.rb b/app/models/user.rb index 8a9e27504d..86201f543f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -531,7 +531,11 @@ class User < ApplicationRecord end def regenerate_feed! - RegenerationWorker.perform_async(account_id) if redis.set("account:#{account_id}:regeneration", true, nx: true, ex: 1.day.seconds) + home_feed = HomeFeed.new(account) + unless home_feed.regenerating? + home_feed.regeneration_in_progress! + RegenerationWorker.perform_async(account_id) + end end def needs_feed_update? diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb index cff38b8e6e..2928c85390 100644 --- a/app/services/follow_service.rb +++ b/app/services/follow_service.rb @@ -46,7 +46,7 @@ class FollowService < BaseService private def mark_home_feed_as_partial! - redis.set("account:#{@source_account.id}:regeneration", true, nx: true, ex: 1.day.seconds) + HomeFeed.new(@source_account).regeneration_in_progress! end def following_not_possible? diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index a591c90913..3eb1d41d92 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -12,7 +12,7 @@ class PrecomputeFeedService < BaseService FeedManager.instance.populate_list(list) unless skip_timeline?(:list, list.id) end ensure - redis.del("account:#{account.id}:regeneration") + HomeFeed.new(account).regeneration_finished! end private diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index d4dcb326bc..4fdf5ba3f9 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -31,7 +31,7 @@ class MergeWorker FeedManager.instance.merge_into_home(@from_account, @into_account) end ensure - redis.del("account:#{into_account_id}:regeneration") + HomeFeed.new(@into_account).regeneration_finished! end def merge_into_list!(into_list_id) diff --git a/spec/models/home_feed_spec.rb b/spec/models/home_feed_spec.rb index 06bb63b1a4..7546fb7861 100644 --- a/spec/models/home_feed_spec.rb +++ b/spec/models/home_feed_spec.rb @@ -42,4 +42,42 @@ RSpec.describe HomeFeed do end end end + + describe '#regenerating?' do + context 'when feed is being generated' do + before do + redis.set("account:#{account.id}:regeneration", true) + end + + it 'returns `true`' do + expect(subject.regenerating?).to be true + end + end + + context 'when feed is not being generated' do + it 'returns `false`' do + expect(subject.regenerating?).to be false + end + end + end + + describe '#regeneration_in_progress!' do + it 'sets the corresponding key in redis' do + expect(redis.exists?("account:#{account.id}:regeneration")).to be false + + subject.regeneration_in_progress! + + expect(redis.exists?("account:#{account.id}:regeneration")).to be true + end + end + + describe '#regeneration_finished!' do + it 'removes the corresponding key from redis' do + redis.set("account:#{account.id}:regeneration", true) + + subject.regeneration_finished! + + expect(redis.exists?("account:#{account.id}:regeneration")).to be false + end + end end