123456789_123456789_123456789_123456789_123456789_

Class: Gem::CompactIndexClient::Cache

Relationships & Source Files
Inherits: Object
Defined in: lib/rubygems/compact_index_client/cache.rb

Overview

Calls the Updater to update the cached files on disk, reads the cached files and returns their contents.

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(directory, fetcher = nil) ⇒ Cache

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 14

def initialize(directory, fetcher = nil)
  @directory = Pathname.new(directory).expand_path
  @updater = Updater.new(fetcher) if fetcher
  @mutex = Thread::Mutex.new
  @endpoints = Set.new

  @info_root = mkdir("info")
  @special_characters_info_root = mkdir("info-special-characters")
  @info_etag_root = mkdir("info-etags")
end

Instance Attribute Details

#directory (readonly)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 12

attr_reader :directory

Instance Method Details

#already_fetched?(remote_path) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 98

def already_fetched?(remote_path)
  @mutex.synchronize { !@endpoints.add?(remote_path) }
end

#checksum_for_file(path) (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 76

def checksum_for_file(path)
  return unless path.file?
  Digest::MD5.file(path).hexdigest
end

#fetch(remote_path, path, etag_path) (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 87

def fetch(remote_path, path, etag_path)
  if already_fetched?(remote_path)
    Gem::CompactIndexClient.debug { "already fetched #{remote_path}" }
  else
    Gem::CompactIndexClient.debug { "fetching #{remote_path}" }
    @updater&.update(remote_path, path, etag_path)
  end

  read(path)
end

#fetch_info(name)

Fetch a single gem's info file without consulting the versions index, refreshing the cached file with a conditional request.

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 46

def fetch_info(name)
  fetch("info/#{name}", info_path(name), info_etag_path(name))
end

#info(name, remote_checksum = nil)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 33

def info(name, remote_checksum = nil)
  path = info_path(name)

  if remote_checksum && remote_checksum != checksum_for_file(path)
    fetch("info/#{name}", path, info_etag_path(name))
  else
    Gem::CompactIndexClient.debug { "update skipped info/#{name} (#{remote_checksum ? "versions index checksum matches local" : "versions index checksum is nil"})" }
    read(path)
  end
end

#info_etag_path(name) (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 71

def info_etag_path(name)
  name = name.to_s
  @info_etag_root.join("#{name}-#{Digest::MD5.hexdigest(name).downcase}")
end

#info_path(name) (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 61

def info_path(name)
  name = name.to_s
  if /[^a-z0-9_-]/.match?(name)
    name += "-#{Digest::MD5.hexdigest(name).downcase}"
    @special_characters_info_root.join(name)
  else
    @info_root.join(name)
  end
end

#mkdir(name) (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 81

def mkdir(name)
  directory.join(name).tap do |dir|
    FileUtils.mkdir_p(dir)
  end
end

#names

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 25

def names
  fetch("names", names_path, names_etag_path)
end

#names_etag_path (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 57

def names_etag_path = directory.join("names.etag")

#names_path (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 56

def names_path = directory.join("names")

#read(path) (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 102

def read(path)
  return unless path.file?
  path.read
end

#reset!

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 50

def reset!
  @mutex.synchronize { @endpoints.clear }
end

#versions

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 29

def versions
  fetch("versions", versions_path, versions_etag_path)
end

#versions_etag_path (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 59

def versions_etag_path = directory.join("versions.etag")

#versions_path (private)

[ GitHub ]

  
# File 'lib/rubygems/compact_index_client/cache.rb', line 58

def versions_path = directory.join("versions")