reports: increase database timeout; add rate limits.
Increase the database timeout to 10 seconds when generating reports. Generating reports tends to be slow, especially for things like graphing posts over time since the beginning of Danbooru. Does not apply to anonymous users. Users must have an account to get higher timeouts so that we can identify users scraping reports too hard. Also add a rate limit of 1 report per 3 seconds to limit abuse.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
class ReportsController < ApplicationController
|
||||
respond_to :html, :json, :xml
|
||||
|
||||
rate_limit :show, rate: 1.0/3.seconds, burst: 15
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
@@ -75,7 +77,16 @@ class ReportsController < ApplicationController
|
||||
@from = params.dig(:search, :from) || 1.month.ago
|
||||
@to = params.dig(:search, :to) || Time.zone.now
|
||||
|
||||
@results = @model.search(params[:search], CurrentUser.user).timeseries(period: @period, from: @from, to: @to, columns: @columns)
|
||||
if CurrentUser.user.is_member? && CurrentUser.user.statement_timeout < 10_000
|
||||
@statement_timeout = 10_000
|
||||
else
|
||||
@statement_timeout = CurrentUser.user.statement_timeout
|
||||
end
|
||||
|
||||
ApplicationRecord.set_timeout(@statement_timeout) do
|
||||
@results = @model.search(params[:search], CurrentUser.user).timeseries(period: @period, from: @from, to: @to, columns: @columns)
|
||||
end
|
||||
|
||||
respond_with(@results)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -134,6 +134,13 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
|
||||
concerning :ActiveRecordExtensions do
|
||||
class_methods do
|
||||
def set_timeout(n)
|
||||
connection.execute("SET STATEMENT_TIMEOUT = #{n}") unless Rails.env.test?
|
||||
yield
|
||||
ensure
|
||||
connection.execute("SET STATEMENT_TIMEOUT = #{CurrentUser.user.statement_timeout}") unless Rails.env.test?
|
||||
end
|
||||
|
||||
def without_timeout
|
||||
connection.execute("SET STATEMENT_TIMEOUT = 0") unless Rails.env.test?
|
||||
yield
|
||||
|
||||
Reference in New Issue
Block a user