mirror of
https://github.com/ruby/ruby.git
synced 2025-08-25 05:55:46 +02:00

This changes the CompactIndexClient to store etags received from the compact index in separate files rather than relying on the MD5 checksum of the file as the etag. Smoothes the upgrade from md5 etags to opaque by generating them when no etag file exists. This should reduce the initial impact of changing the caching behavior by reducing cache misses when the MD5 etag is the same. Eventually, the MD5 behavior should be retired and the etag should be considered completely opaque with no assumption that MD5 would match.
33 lines
1.2 KiB
Ruby
33 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "helpers/compact_index"
|
|
|
|
class CompactIndexConcurrentDownload < CompactIndexAPI
|
|
get "/versions" do
|
|
versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
|
|
"localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions")
|
|
|
|
# Verify the original content hasn't been deleted, e.g. on a retry
|
|
data = File.binread(versions)
|
|
data == "created_at" || raise("Original file should be present with expected content")
|
|
|
|
# Verify this is only requested once for a partial download
|
|
env["HTTP_RANGE"] == "bytes=#{data.bytesize - 1}-" || raise("Missing Range header for expected partial download")
|
|
|
|
# Overwrite the file in parallel, which should be then overwritten
|
|
# after a successful download to prevent corruption
|
|
File.open(versions, "w") {|f| f.puts "another process" }
|
|
|
|
etag_response do
|
|
file = tmp("versions.list")
|
|
FileUtils.rm_f(file)
|
|
file = CompactIndex::VersionsFile.new(file.to_s)
|
|
file.create(gems)
|
|
file.contents
|
|
end
|
|
end
|
|
end
|
|
|
|
require_relative "helpers/artifice"
|
|
|
|
Artifice.activate_with(CompactIndexConcurrentDownload)
|