From fdc3ff7c2d538751fc5e761fae33fc007294a540 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 12 Jul 2023 17:06:00 +0200 Subject: [PATCH] Change notifications API to use a replica (#25874) --- app/controllers/api/v1/notifications_controller.rb | 8 ++++++-- app/controllers/api/v1/timelines/home_controller.rb | 2 +- app/controllers/application_controller.rb | 1 + app/helpers/database_helper.rb | 11 +++++++++++ app/workers/feed_insert_worker.rb | 5 +++-- app/workers/merge_worker.rb | 5 +++-- app/workers/regeneration_worker.rb | 5 +++-- app/workers/unmerge_worker.rb | 5 +++-- 8 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 app/helpers/database_helper.rb diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb index 8414f6b25..406ab9753 100644 --- a/app/controllers/api/v1/notifications_controller.rb +++ b/app/controllers/api/v1/notifications_controller.rb @@ -9,8 +9,12 @@ class Api::V1::NotificationsController < Api::BaseController DEFAULT_NOTIFICATIONS_LIMIT = 40 def index - @notifications = load_notifications - render json: @notifications, each_serializer: REST::NotificationSerializer, relationships: StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id) + with_read_replica do + @notifications = load_notifications + @relationships = StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id) + end + + render json: @notifications, each_serializer: REST::NotificationSerializer, relationships: @relationships end def show diff --git a/app/controllers/api/v1/timelines/home_controller.rb b/app/controllers/api/v1/timelines/home_controller.rb index 0ee28ef04..83b8cb4c6 100644 --- a/app/controllers/api/v1/timelines/home_controller.rb +++ b/app/controllers/api/v1/timelines/home_controller.rb @@ -6,7 +6,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController after_action :insert_pagination_headers, unless: -> { @statuses.empty? } def show - ApplicationRecord.connected_to(role: :read, prevent_writes: true) do + with_read_replica do @statuses = load_statuses @relationships = StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f966b18ab..66886b451 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base include SessionTrackingConcern include CacheConcern include DomainControlHelper + include DatabaseHelper helper_method :current_account helper_method :current_session diff --git a/app/helpers/database_helper.rb b/app/helpers/database_helper.rb new file mode 100644 index 000000000..965eeaf41 --- /dev/null +++ b/app/helpers/database_helper.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module DatabaseHelper + def with_read_replica(&block) + ApplicationRecord.connected_to(role: :read, prevent_writes: true, &block) + end + + def with_primary(&block) + ApplicationRecord.connected_to(role: :primary, &block) + end +end diff --git a/app/workers/feed_insert_worker.rb b/app/workers/feed_insert_worker.rb index 47826c211..fd7dbd30d 100644 --- a/app/workers/feed_insert_worker.rb +++ b/app/workers/feed_insert_worker.rb @@ -2,9 +2,10 @@ class FeedInsertWorker include Sidekiq::Worker + include DatabaseHelper def perform(status_id, id, type = 'home', options = {}) - ApplicationRecord.connected_to(role: :primary) do + with_primary do @type = type.to_sym @status = Status.find(status_id) @options = options.symbolize_keys @@ -18,7 +19,7 @@ class FeedInsertWorker end end - ApplicationRecord.connected_to(role: :read, prevent_writes: true) do + with_read_replica do check_and_insert end rescue ActiveRecord::RecordNotFound diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index 50cfcc3f0..8e1614ad2 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -3,14 +3,15 @@ class MergeWorker include Sidekiq::Worker include Redisable + include DatabaseHelper def perform(from_account_id, into_account_id) - ApplicationRecord.connected_to(role: :primary) do + with_primary do @from_account = Account.find(from_account_id) @into_account = Account.find(into_account_id) end - ApplicationRecord.connected_to(role: :read, prevent_writes: true) do + with_read_replica do FeedManager.instance.merge_into_home(@from_account, @into_account) end rescue ActiveRecord::RecordNotFound diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb index 5ac095e65..4228f897d 100644 --- a/app/workers/regeneration_worker.rb +++ b/app/workers/regeneration_worker.rb @@ -2,15 +2,16 @@ class RegenerationWorker include Sidekiq::Worker + include DatabaseHelper sidekiq_options lock: :until_executed def perform(account_id, _ = :home) - ApplicationRecord.connected_to(role: :primary) do + with_primary do @account = Account.find(account_id) end - ApplicationRecord.connected_to(role: :read, prevent_writes: true) do + with_read_replica do PrecomputeFeedService.new.call(@account) end rescue ActiveRecord::RecordNotFound diff --git a/app/workers/unmerge_worker.rb b/app/workers/unmerge_worker.rb index f911ea2f9..e8ac535df 100644 --- a/app/workers/unmerge_worker.rb +++ b/app/workers/unmerge_worker.rb @@ -2,16 +2,17 @@ class UnmergeWorker include Sidekiq::Worker + include DatabaseHelper sidekiq_options queue: 'pull' def perform(from_account_id, into_account_id) - ApplicationRecord.connected_to(role: :primary) do + with_primary do @from_account = Account.find(from_account_id) @into_account = Account.find(into_account_id) end - ApplicationRecord.connected_to(role: :read, prevent_writes: true) do + with_read_replica do FeedManager.instance.unmerge_from_home(@from_account, @into_account) end rescue ActiveRecord::RecordNotFound