Commit 1cc2383b authored by Stan Hu's avatar Stan Hu

Merge branch 'andysoiron/start-http-read-total-timer-after-first-block' into 'master'

Improve ReadTotalTimeout to start on reading first block

See merge request gitlab-org/gitlab!77879
parents 56835738 7448b792
...@@ -49,11 +49,12 @@ module Gitlab ...@@ -49,11 +49,12 @@ module Gitlab
return httparty_perform_request(http_method, path, options_with_timeouts, &block) return httparty_perform_request(http_method, path, options_with_timeouts, &block)
end end
start_time = Gitlab::Metrics::System.monotonic_time start_time = nil
read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT) read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT)
tracked_timeout_error = false tracked_timeout_error = false
httparty_perform_request(http_method, path, options_with_timeouts) do |fragment| httparty_perform_request(http_method, path, options_with_timeouts) do |fragment|
start_time ||= Gitlab::Metrics::System.monotonic_time
elapsed = Gitlab::Metrics::System.monotonic_time - start_time elapsed = Gitlab::Metrics::System.monotonic_time - start_time
if elapsed > read_total_timeout if elapsed > read_total_timeout
......
...@@ -29,14 +29,42 @@ RSpec.describe Gitlab::HTTP do ...@@ -29,14 +29,42 @@ RSpec.describe Gitlab::HTTP do
context 'when reading the response is too slow' do context 'when reading the response is too slow' do
before do before do
# Override Net::HTTP to add a delay between sending each response chunk
mocked_http = Class.new(Net::HTTP) do
def request(*)
super do |response|
response.instance_eval do
def read_body(*)
@body.each do |fragment|
sleep 0.002.seconds
yield fragment if block_given?
end
end
end
yield response if block_given?
response
end
end
end
@original_net_http = Net.send(:remove_const, :HTTP)
Net.send(:const_set, :HTTP, mocked_http)
stub_const("#{described_class}::DEFAULT_READ_TOTAL_TIMEOUT", 0.001.seconds) stub_const("#{described_class}::DEFAULT_READ_TOTAL_TIMEOUT", 0.001.seconds)
WebMock.stub_request(:post, /.*/).to_return do |request| WebMock.stub_request(:post, /.*/).to_return do |request|
sleep 0.002.seconds { body: %w(a b), status: 200 }
{ body: 'I\'m slow', status: 200 }
end end
end end
after do
Net.send(:remove_const, :HTTP)
Net.send(:const_set, :HTTP, @original_net_http)
end
let(:options) { {} } let(:options) { {} }
subject(:request_slow_responder) { described_class.post('http://example.org', **options) } subject(:request_slow_responder) { described_class.post('http://example.org', **options) }
...@@ -51,7 +79,7 @@ RSpec.describe Gitlab::HTTP do ...@@ -51,7 +79,7 @@ RSpec.describe Gitlab::HTTP do
end end
it 'still calls the block' do it 'still calls the block' do
expect { |b| described_class.post('http://example.org', **options, &b) }.to yield_with_args expect { |b| described_class.post('http://example.org', **options, &b) }.to yield_successive_args('a', 'b')
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment