Moving Salmon notifications to background processing, fixing mini-profiler

behaviour with Turbolinks enabled, optimizing Rabl for production
This commit is contained in:
Eugen Rochko 2016-03-26 13:42:10 +01:00
parent da4b675aca
commit 85b00d19b8
15 changed files with 49 additions and 35 deletions

View File

@ -51,6 +51,7 @@ end
group :test do group :test do
gem 'simplecov', require: false gem 'simplecov', require: false
gem 'webmock' gem 'webmock'
gem 'rspec-sidekiq'
end end
group :development do group :development do
@ -59,6 +60,8 @@ group :development do
gem 'better_errors' gem 'better_errors'
gem 'binding_of_caller' gem 'binding_of_caller'
gem 'letter_opener' gem 'letter_opener'
gem 'bullet'
gem 'memory_profiler'
end end
group :production do group :production do

View File

@ -47,6 +47,9 @@ GEM
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
builder (3.2.2) builder (3.2.2)
bullet (5.0.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.9.0)
climate_control (0.0.3) climate_control (0.0.3)
activesupport (>= 3.0) activesupport (>= 3.0)
cocaine (0.5.8) cocaine (0.5.8)
@ -139,6 +142,7 @@ GEM
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.6.3) mail (2.6.3)
mime-types (>= 1.16, < 3) mime-types (>= 1.16, < 3)
memory_profiler (0.9.6)
method_source (0.8.2) method_source (0.8.2)
mime-types (2.99.1) mime-types (2.99.1)
mimemagic (0.3.0) mimemagic (0.3.0)
@ -252,6 +256,9 @@ GEM
rspec-expectations (~> 3.4.0) rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0) rspec-mocks (~> 3.4.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.4.0)
rspec-sidekiq (2.2.0)
rspec (~> 3.0, >= 3.0.0)
sidekiq (>= 2.4.0)
rspec-support (3.4.1) rspec-support (3.4.1)
rubocop (0.38.0) rubocop (0.38.0)
parser (>= 2.3.0.6, < 3.0) parser (>= 2.3.0.6, < 3.0)
@ -316,6 +323,7 @@ GEM
unf_ext unf_ext
unf_ext (0.0.7.2) unf_ext (0.0.7.2)
unicode-display_width (1.0.2) unicode-display_width (1.0.2)
uniform_notifier (1.9.0)
warden (1.2.6) warden (1.2.6)
rack (>= 1.0) rack (>= 1.0)
web-console (2.3.0) web-console (2.3.0)
@ -336,6 +344,7 @@ DEPENDENCIES
addressable addressable
better_errors better_errors
binding_of_caller binding_of_caller
bullet
coffee-rails (~> 4.1.0) coffee-rails (~> 4.1.0)
devise devise
doorkeeper doorkeeper
@ -352,6 +361,7 @@ DEPENDENCIES
jbuilder (~> 2.0) jbuilder (~> 2.0)
jquery-rails jquery-rails
letter_opener letter_opener
memory_profiler
nokogiri nokogiri
oj oj
onebox onebox
@ -370,6 +380,7 @@ DEPENDENCIES
rails_autolink rails_autolink
redis (~> 3.2) redis (~> 3.2)
rspec-rails rspec-rails
rspec-sidekiq
rubocop rubocop
sass-rails (~> 5.0) sass-rails (~> 5.0)
sdoc (~> 0.4.0) sdoc (~> 0.4.0)

View File

@ -1,2 +1,5 @@
$(document).on 'turbolinks:load', -> $ ->
window.MiniProfiler.pageTransition() unless typeof window.MiniProfiler == 'undefined' $(document).on 'turbolinks:load', ->
unless typeof window.MiniProfiler == 'undefined'
window.MiniProfiler.init()
window.MiniProfiler.pageTransition()

View File

@ -16,7 +16,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
end end
end end
def after_sign_up_path_for(resource) def after_sign_up_path_for(_resource)
root_path root_path
end end
end end

View File

@ -17,7 +17,7 @@ class Status < ActiveRecord::Base
validates :text, presence: true, if: Proc.new { |s| s.local? && !s.reblog? } validates :text, presence: true, if: Proc.new { |s| s.local? && !s.reblog? }
scope :with_counters, -> { select('statuses.*, (select count(r.id) from statuses as r where r.reblog_of_id = statuses.id) as reblogs_count, (select count(f.id) from favourites as f where f.status_id = statuses.id) as favourites_count') } scope :with_counters, -> { select('statuses.*, (select count(r.id) from statuses as r where r.reblog_of_id = statuses.id) as reblogs_count, (select count(f.id) from favourites as f where f.status_id = statuses.id) as favourites_count') }
scope :with_includes, -> { includes(:account, :mentions, :stream_entry, reblog: [:account, :mentions], thread: [:account, :mentions]) } scope :with_includes, -> { includes(:account, :mentions, :stream_entry, reblog: [:account, :mentions], thread: :account) }
def local? def local?
self.uri.nil? self.uri.nil?

View File

@ -10,15 +10,9 @@ class FavouriteService < BaseService
if status.local? if status.local?
NotificationMailer.favourite(status, account).deliver_later NotificationMailer.favourite(status, account).deliver_later
else else
send_interaction_service.(favourite.stream_entry, status.account) NotificationWorker.perform_async(favourite.stream_entry.id, status.account_id)
end end
favourite favourite
end end
private
def send_interaction_service
@send_interaction_service ||= SendInteractionService.new
end
end end

View File

@ -8,7 +8,7 @@ class FollowService < BaseService
return nil if target_account.nil? return nil if target_account.nil?
follow = source_account.follow!(target_account) follow = source_account.follow!(target_account)
send_interaction_service.(follow.stream_entry, target_account) NotificationWorker.perform_async(follow.stream_entry.id, target_account.id)
source_account.ping!(account_url(source_account, format: 'atom'), [Rails.configuration.x.hub_url]) source_account.ping!(account_url(source_account, format: 'atom'), [Rails.configuration.x.hub_url])
follow follow
end end
@ -18,8 +18,4 @@ class FollowService < BaseService
def follow_remote_account_service def follow_remote_account_service
@follow_remote_account_service ||= FollowRemoteAccountService.new @follow_remote_account_service ||= FollowRemoteAccountService.new
end end
def send_interaction_service
@send_interaction_service ||= SendInteractionService.new
end
end end

View File

@ -24,7 +24,7 @@ class ProcessMentionsService < BaseService
if mentioned_account.local? if mentioned_account.local?
NotificationMailer.mention(mentioned_account, status).deliver_later NotificationMailer.mention(mentioned_account, status).deliver_later
else else
send_interaction_service.(status.stream_entry, mentioned_account) NotificationWorker.perform_async(status.stream_entry.id, mentioned_account.id)
end end
end end
end end
@ -34,8 +34,4 @@ class ProcessMentionsService < BaseService
def follow_remote_account_service def follow_remote_account_service
@follow_remote_account_service ||= FollowRemoteAccountService.new @follow_remote_account_service ||= FollowRemoteAccountService.new
end end
def send_interaction_service
@send_interaction_service ||= SendInteractionService.new
end
end end

View File

@ -5,13 +5,13 @@ class ReblogService < BaseService
# @return [Status] # @return [Status]
def call(account, reblogged_status) def call(account, reblogged_status)
reblog = account.statuses.create!(reblog: reblogged_status, text: '') reblog = account.statuses.create!(reblog: reblogged_status, text: '')
fan_out_on_write_service.(reblog) DistributionWorker.perform_async(reblog.id)
account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url])
if reblogged_status.local? if reblogged_status.local?
NotificationMailer.reblog(reblogged_status, account).deliver_later NotificationMailer.reblog(reblogged_status, account).deliver_later
else else
send_interaction_service.(reblog.stream_entry, reblogged_status.account) NotificationWorker.perform_async(reblog.stream_entry.id, reblogged_status.account_id)
end end
reblog reblog
@ -22,8 +22,4 @@ class ReblogService < BaseService
def send_interaction_service def send_interaction_service
@send_interaction_service ||= SendInteractionService.new @send_interaction_service ||= SendInteractionService.new
end end
def fan_out_on_write_service
@fan_out_on_write_service ||= FanOutOnWriteService.new
end
end end

View File

@ -4,12 +4,6 @@ class UnfollowService < BaseService
# @param [Account] target_account Which to unfollow # @param [Account] target_account Which to unfollow
def call(source_account, target_account) def call(source_account, target_account)
follow = source_account.unfollow!(target_account) follow = source_account.unfollow!(target_account)
send_interaction_service.(follow.stream_entry, target_account) unless target_account.local? NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) unless target_account.local?
end
private
def send_interaction_service
@send_interaction_service ||= SendInteractionService.new
end end
end end

View File

@ -0,0 +1,7 @@
class NotificationWorker
include Sidekiq::Worker
def perform(stream_entry_id, target_account_id)
SendInteractionService.new.(StreamEntry.find(stream_entry_id), Account.find(target_account_id))
end
end

View File

@ -40,4 +40,10 @@ Rails.application.configure do
# config.action_view.raise_on_missing_translations = true # config.action_view.raise_on_missing_translations = true
config.action_mailer.delivery_method = :letter_opener config.action_mailer.delivery_method = :letter_opener
config.after_initialize do
Bullet.enable = true
Bullet.bullet_logger = true
Bullet.rails_logger = true
end
end end

View File

@ -55,7 +55,7 @@ Rails.application.configure do
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production. # Use a different cache store in production.
# config.cache_store = :mem_cache_store config.cache_store = :memory_store, size: 128.megabytes
# Enable serving of images, stylesheets, and JavaScripts from an asset server. # Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com' # config.action_controller.asset_host = 'http://assets.example.com'

View File

@ -1,3 +1,6 @@
Rabl.configure do |config| Rabl.configure do |config|
config.cache_all_output = true
config.cache_sources = !!Rails.env.production?
config.include_json_root = false config.include_json_root = false
config.view_paths = [Rails.root.join('app/views')]
end end

View File

@ -9,6 +9,7 @@ require 'webmock/rspec'
ActiveRecord::Migration.maintain_test_schema! ActiveRecord::Migration.maintain_test_schema!
WebMock.disable_net_connect! WebMock.disable_net_connect!
Sidekiq::Testing.inline!
RSpec.configure do |config| RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures" config.fixture_path = "#{::Rails.root}/spec/fixtures"
@ -20,6 +21,10 @@ RSpec.configure do |config|
config.include Devise::TestHelpers, type: :view config.include Devise::TestHelpers, type: :view
end end
RSpec::Sidekiq.configure do |config|
config.warn_when_jobs_not_processed_by_sidekiq = false
end
def request_fixture(name) def request_fixture(name)
File.read(File.join(Rails.root, 'spec', 'fixtures', 'requests', name)) File.read(File.join(Rails.root, 'spec', 'fixtures', 'requests', name))
end end