~cytrogen/masto-fe

fdc3ff7c2d538751fc5e761fae33fc007294a540 — Eugen Rochko 2 years ago 82e477b
Change notifications API to use a replica (#25874)

M app/controllers/api/v1/notifications_controller.rb => app/controllers/api/v1/notifications_controller.rb +6 -2
@@ 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

M app/controllers/api/v1/timelines/home_controller.rb => app/controllers/api/v1/timelines/home_controller.rb +1 -1
@@ 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

M app/controllers/application_controller.rb => app/controllers/application_controller.rb +1 -0
@@ 10,6 10,7 @@ class ApplicationController < ActionController::Base
  include SessionTrackingConcern
  include CacheConcern
  include DomainControlHelper
  include DatabaseHelper

  helper_method :current_account
  helper_method :current_session

A app/helpers/database_helper.rb => app/helpers/database_helper.rb +11 -0
@@ 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

M app/workers/feed_insert_worker.rb => app/workers/feed_insert_worker.rb +3 -2
@@ 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

M app/workers/merge_worker.rb => app/workers/merge_worker.rb +3 -2
@@ 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

M app/workers/regeneration_worker.rb => app/workers/regeneration_worker.rb +3 -2
@@ 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

M app/workers/unmerge_worker.rb => app/workers/unmerge_worker.rb +3 -2
@@ 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