-
-
Save casperisfine/6e25454406322be4ecde976d15392ca0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "benchmark" | |
require "google/cloud/storage" | |
def measure(&block) | |
duration = Benchmark.realtime(&block) | |
puts "took: #{duration.round(1)}s" | |
end | |
def run_bench | |
bucket = Google::Cloud::Storage.new( | |
project: 'shopify-ci' | |
).bucket('byroot-testing', skip_lookup: true) | |
file_name = 'random-500M.bin' | |
local_path = "/tmp/random-500M.bin" | |
File.delete(local_path) if File.exist?(local_path) | |
measure do | |
file = bucket.file(file_name, skip_lookup: true) | |
puts file.download("/tmp/random-500M.bin", verify: :none) | |
end | |
File.delete(local_path) if File.exist?(local_path) | |
end | |
puts '+++ Pre patch' | |
run_bench | |
class Google::Apis::Core::DownloadCommand | |
def execute_once(client, &block) | |
request_header = header.dup | |
apply_request_options(request_header) | |
download_offset = nil | |
if @offset > 0 | |
logger.debug { sprintf('Resuming download from offset %d', @offset) } | |
request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset) | |
end | |
http_res = client.get(url.to_s, | |
query: query, | |
header: request_header, | |
follow_redirect: true) do |res, socket, content_length| | |
status = res.http_header.status_code.to_i | |
next unless OK_STATUS.include?(status) | |
download_offset = (status == 206 ? @offset : 0) | |
# logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) } | |
p [:copy_stream, content_length] | |
bytes_read = IO.copy_stream(socket, @download_io, content_length) | |
@offset += bytes_read | |
bytes_read | |
end | |
@download_io.flush | |
if @close_io_on_finish | |
result = nil | |
else | |
result = @download_io | |
end | |
check_status(http_res.status.to_i, http_res.header, http_res.body) | |
success(result, &block) | |
rescue => e | |
@download_io.flush | |
error(e, rethrow: true, &block) | |
end | |
end | |
class HTTPClient | |
def follow_redirect(method, uri, query, body, header, &block) | |
uri = to_resource_url(uri) | |
if block | |
b = adapt_block(&block) | |
filtered_block = proc { |r, *args| | |
b.call(r, *args) if r.ok? | |
} | |
end | |
if HTTP::Message.file?(body) | |
pos = body.pos rescue nil | |
end | |
retry_number = 0 | |
previous = nil | |
request_query = query | |
while retry_number < @follow_redirect_count | |
body.pos = pos if pos | |
res = do_request(method, uri, request_query, body, header, &filtered_block) | |
res.previous = previous | |
if res.redirect? | |
if res.header['location'].empty? | |
raise BadResponseError.new("Missing Location header for redirect", res) | |
end | |
method = :get if res.see_other? # See RFC2616 10.3.4 | |
uri = urify(@redirect_uri_callback.call(uri, res)) | |
# To avoid duped query parameter. 'location' must include query part. | |
request_query = nil | |
previous = res | |
retry_number += 1 | |
else | |
return res | |
end | |
end | |
raise BadResponseError.new("retry count exceeded", res) | |
end | |
def adapt_block(&block) | |
return block | |
end | |
def do_get_block(req, proxy, conn, &block) | |
@request_filter.each do |filter| | |
filter.filter_request(req) | |
end | |
if str = @test_loopback_response.shift | |
dump_dummy_request_response(req.http_body.dump, str) if @debug_dev | |
res = HTTP::Message.new_response(str, req.header) | |
conn.push(res) | |
return res | |
end | |
content = block ? nil : '' | |
res = HTTP::Message.new_response(content, req.header) | |
@debug_dev << "= Request\n\n" if @debug_dev | |
sess = @session_manager.query(req, proxy) | |
res.peer_cert = sess.ssl_peer_cert | |
@debug_dev << "\n\n= Response\n\n" if @debug_dev | |
do_get_header(req, res, sess) | |
conn.push(res) | |
sess.get_body do |socket, content_length| | |
p [:get_body, content_length, block] | |
# set_encoding(part, res.body_encoding) | |
if block | |
block.call(res, socket, content_length) | |
else | |
content << part | |
end | |
end | |
# there could be a race condition but it's OK to cache unreusable | |
# connection because we do retry for that case. | |
@session_manager.keep(sess) unless sess.closed? | |
commands = @request_filter.collect { |filter| | |
filter.filter_response(req, res) | |
} | |
if commands.find { |command| command == :retry } | |
raise RetryableResponse.new(res) | |
end | |
res | |
end | |
class Session | |
def read_body_length(&block) | |
return nil if @content_length == 0 | |
@content_length -= block.call(@socket, @content_length) | |
end | |
end | |
end | |
puts '+++ Post patch' | |
run_bench |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment