-
-
Save rinaldifonseca/961041 to your computer and use it in GitHub Desktop.
Rack app for caching RubyGems files. Very useful in our build server that sometimes fails due to our network or rubygems.org timeout.
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 "./rubygems_proxy" | |
run RubygemsProxy |
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 "open-uri" | |
require "fileutils" | |
require "logger" | |
class RubygemsProxy | |
attr_reader :env | |
def self.call(env) | |
new(env).run | |
end | |
def initialize(env) | |
@env = env | |
end | |
def run | |
[200, {"Content-Type" => "application/octet-stream"}, [contents]] | |
end | |
private | |
def logger | |
@logger ||= Logger.new(STDOUT) | |
end | |
def cache_dir | |
File.expand_path "../cache", __FILE__ | |
end | |
def contents | |
if cached? && valid? | |
logger.info "Read from cache: #{filepath}" | |
open(filepath).read | |
else | |
logger.info "Read from interwebz: #{url}" | |
open(url).read.tap {|content| save(content)} | |
end | |
rescue Exception => error | |
# Just try to load from file if something goes wrong. | |
# This includes HTTP timeout, or something. | |
# If it fails again, we won't have any files anyway! | |
logger.error "Error: #{error.class} => #{error.message}" | |
open(filepath).read | |
end | |
def save(contents) | |
FileUtils.mkdir_p File.dirname(filepath) | |
File.open(filepath, "wb") {|handler| handler << contents} | |
end | |
def valid? | |
filepath =~ /specs\..+\.gz$/ ? Time.now - File.mtime(filepath) < 300 : true | |
end | |
def cached? | |
File.file?(filepath) | |
end | |
def filepath | |
File.join(cache_dir, env["PATH_INFO"]) | |
end | |
def url | |
File.join("http://rubygems.org", env["PATH_INFO"]) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment