Optimization:Throttle Tag Index Endpoints (#12520)

This commit is contained in:
Molly Struve 2021-02-03 10:14:54 -06:00 committed by GitHub
parent cb43c9f808
commit 2e6397d319
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 8 deletions

View file

@ -30,8 +30,8 @@ module Rack
track_and_return_ip(request.env["HTTP_FASTLY_CLIENT_IP"])
end
throttle("message_throttle", limit: 2, period: 1) do |request|
if request.path.starts_with?("/messages") && request.post?
throttle("message_tag_throttle", limit: 2, period: 1) do |request|
if message_or_tag_request(request)
track_and_return_ip(request.env["HTTP_FASTLY_CLIENT_IP"])
end
end
@ -42,5 +42,10 @@ module Rack
Honeycomb.add_field("fastly_client_ip", ip_address)
ip_address.to_s
end
def self.message_or_tag_request(request)
(request.path.starts_with?("/messages") && request.post?) ||
request.path.include?("/t/")
end
end
end

View file

@ -95,7 +95,7 @@ describe Rack::Attack, type: :request, throttle: true do
end
end
describe "message_throttle" do
describe "message_tag_throttle" do
let(:user) { create(:user) }
let(:chat_channel) { create(:chat_channel) }
let(:new_message) do
@ -106,6 +106,8 @@ describe Rack::Attack, type: :request, throttle: true do
chat_channel_id: chat_channel.id
}
end
let(:headers) { { "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" } }
let(:dif_headers) { { "HTTP_FASTLY_CLIENT_IP" => "1.1.1.1" } }
before do
allow(Pusher).to receive(:trigger).and_return(true)
@ -113,22 +115,46 @@ describe Rack::Attack, type: :request, throttle: true do
end
it "throttles creating messages" do
headers = { "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" }
dif_headers = { "HTTP_FASTLY_CLIENT_IP" => "1.1.1.1" }
Timecop.freeze do
valid_responses = Array.new(2).map do
post messages_path, params: { message: new_message }, headers: headers
end
throttled_response = post messages_path, params: { message: new_message }, headers: headers
new_api_response = post messages_path, params: { message: new_message }, headers: dif_headers
new_response = post messages_path, params: { message: new_message }, headers: dif_headers
valid_responses.each { |r| expect(r).not_to eq(429) }
expect(throttled_response).to eq(429)
expect(new_api_response).not_to eq(429)
expect(new_response).not_to eq(429)
expect(Honeycomb).to have_received(:add_field).with("fastly_client_ip", "5.6.7.8").exactly(6).times
expect(Honeycomb).to have_received(:add_field).with("fastly_client_ip", "1.1.1.1").exactly(2).times
end
end
# rubocop:disable RSpec/AnyInstance, RSpec/ExampleLength
it "throttles viewing tags" do
allow_any_instance_of(StoriesController).to receive(:cached_tagged_count).and_return(0)
allow_any_instance_of(StoriesController).to receive(:stories_by_timeframe).and_return(Article.none)
allow_any_instance_of(Articles::Feeds::LargeForemExperimental).to receive(
:published_articles_by_tag,
).and_return(Article.none)
tag_path = "/t/#{create(:tag).name}"
get tag_path, headers: headers # warm up the slow endpoint
Timecop.freeze do
valid_responses = Array.new(2).map do
get tag_path, headers: headers
end
throttled_response = get tag_path, headers: headers
new_response = get tag_path, headers: dif_headers
expect(valid_responses.first).not_to eq(429)
expect(throttled_response).to eq(429)
expect(new_response).not_to eq(429)
expect(Honeycomb).to have_received(:add_field).with("fastly_client_ip", "5.6.7.8").exactly(8).times
expect(Honeycomb).to have_received(:add_field).with("fastly_client_ip", "1.1.1.1").exactly(2).times
end
end
# rubocop:enable RSpec/AnyInstance, RSpec/ExampleLength
end
end