У меня есть приложение Rails 4, которое иногда зависает на 5 минут за раз, оставляя сайт недоступным для всех.Иногда, когда запускается HTTP POST, исходящий из / plays, сервер полностью блокируется и перестает отвечать на запросы.
Согласно этому источнику ниже, ActiveRecord следует использовать экономно, а также сокращать использование .all с find_in_batches
https://chaione.com/blog/dealing-massive-data-rails/ActiveRecord
Мое подозрение было в том, что set_plays в PlaysController, возможно, был виновником, но теперь я больше склоняюсь к неправильному использованию функции кэша рельсов, так как эта проблема возникает с нерегулярными интервалами и являетсятрудно воспроизвести.
Ниже приведен фрагмент от контроллера воспроизведения.
class PlaysController < ApplicationController
helper PlaysHelper
load_and_authorize_resource
before_action :set_plays, only: [:index, :create]
before_action :set_play, only: [:show, :edit, :update, :destroy]
respond_to :html, :json
layout "layouts/tabs"
before_filter :title
before_filter :set_links
def new
@play = Play.new
respond_with(@play)
end
def create
@play = Play.new(play_params)
@play.show ||= @play.get_show(current_user)
if pbn = params[:playbox_number]
@play.playbox_number = pbn
end
if @play.save
begin
report_play_to_shoutcast(@play) if Rails.env.production?
rescue StandardError => e
flash[:error] = "Unable to report play to SHOUTcast #{e.inspect}\n#{e.backtrace[0]}"
end
begin
report_play_to_tunein(@play) if Rails.env.production?
rescue StandardError => e
flash[:error] = "Unable to report play to tunein #{e.inspect}\n#{e.backtrace[0]}"
end
# clear the cache of anything with play information in it
clear_plays_cache
# go ahead and reset the last_play cache, because we already have the value in hand
set_last_play(@play)
@play = Play.new
render(action: :index)
else
respond_with(@play)
end
end
private
def set_play
@play = Play.find(params[:id])
end
def set_plays
@plays = Play.all.paginate(page: params[:page], per_page: 50, total_entries: plays_count() ).order('created_at DESC').preload(:show,:playbox)
end
def play_params
params.require(:play).permit(:artist, :album, :track, :show_id)
end
end
И часть помощника приложения
module ApplicationHelper
def set_last_play(play)
Rails.cache.write("plays__last_play", play, expires_in: 5.minutes, race_condition_ttl: 10.seconds)
end # set_last_play
def last_play
@last_play ||= Rails.cache.fetch("plays__last_play", expires_in: 5.minutes, race_condition_ttl: 10.seconds) do
Play.order("created_at").includes(:show).last || Play.new(album: "", artist: "", track: "", show: nil)
end
end # last_play
def plays_count
# only one 1 underscore (_) in order to avoid being eliminated by clear_plays_cache
@plays_count ||= Rails.cache.fetch("plays_count", expires_in: 5.hours, race_condition_ttl: 10.seconds) do
Play.count
end
end
def clear_plays_cache
Rails.cache.delete_matched('plays__')
end # clear_plays_cache
end
Вот примервыдача из лог-файла
I, [2019-06-19T08:25:37.659021 #5772] INFO -- : Started POST "/plays" for 127.0.0.1 at 2019-06-19 08:25:37 -0400
I, [2019-06-19T08:25:37.659021 #5772] INFO -- : Processing by PlaysController#create as HTML
I, [2019-06-19T08:25:37.659021 #5772] INFO -- : Parameters: {"utf8"=>"✓", "authenticity_token"=>"REDACTED", "playbox_number"=>"", "play"=>{"artist"=>"Band", "track"=>"Song", "album"=>"Single", "show_id"=>"720"}, "commit"=>"Create Play"}
I, [2019-06-19T08:26:07.209014 #5772] INFO -- : Rendered plays/_playbox_requirements.html.erb (15.7ms)
I, [2019-06-19T08:26:07.209014 #5772] INFO -- : Rendered plays/_form.html.erb (15.7ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered plays/_table.html.erb (46.9ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered plays/index.html.erb within layouts/tabs (62.5ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered plays/_lastwidget.html.erb (0.0ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered application/_login.overlay.html.erb (0.0ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered layouts/application.html.erb (0.0ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered layouts/bootstrap.html.erb (0.0ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Rendered layouts/bootstrap-wide.html.erb (0.0ms)
I, [2019-06-19T08:26:07.255871 #5772] INFO -- : Completed 200 OK in 276754ms (Views: 66.8ms | ActiveRecord: 35996.5ms)