Skip to content

Commit

Permalink
Faster bundler API support.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomlea committed Mar 13, 2012
1 parent 89a965a commit 50dc3bb
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 11 deletions.
7 changes: 6 additions & 1 deletion Rakefile
Expand Up @@ -30,6 +30,11 @@ Rake::TestTask.new("test:requests") do |t|
t.pattern = "test/requests/**/*_test.rb"
end

Rake::TestTask.new("test:units") do |t|
t.libs << "test" << "lib"
t.pattern = "test/units/**/*_test.rb"
end

task :st => "test:smoke"
task :test => ["test:requests", "test:integration"]
task :test => ["test:units", "test:requests", "test:integration"]
task :default => :test
28 changes: 18 additions & 10 deletions lib/geminabox.rb
Expand Up @@ -31,6 +31,7 @@ def fixup_bundler_rubygems!
end

autoload :GemVersionCollection, "geminabox/gem_version_collection"
autoload :DiskCache, "geminabox/disk_cache"

before do
headers 'X-Powered-By' => "geminabox #{GeminaboxVersion}"
Expand All @@ -48,17 +49,19 @@ def fixup_bundler_rubygems!
end

get '/api/v1/dependencies' do
query_gems = params[:gems].split(',')
deps = load_gems.gems.select {|gem| query_gems.include?(gem.name) }.map do |gem|
spec = spec_for(gem.name, gem.number)
{
:name => gem.name,
:number => gem.number.version,
:platform => gem.platform,
:dependencies => spec.dependencies.select {|dep| dep.type == :runtime}.map {|dep| [dep.name, dep.requirement.to_s] }
}
disk_cache.cache(params[:gems]) do
query_gems = params[:gems].split(',')
deps = load_gems.gems.select {|gem| query_gems.include?(gem.name) }.map do |gem|
spec = spec_for(gem.name, gem.number)
{
:name => gem.name,
:number => gem.number.version,
:platform => gem.platform,
:dependencies => spec.dependencies.select {|dep| dep.type == :runtime}.map {|dep| [dep.name, dep.requirement.to_s] }
}
end
Marshal.dump(deps)
end
Marshal.dump(deps)
end

get '/upload' do
Expand Down Expand Up @@ -159,6 +162,7 @@ def reindex(force_rebuild = false)
reindex(:force_rebuild)
end
end
disk_cache.flush
end

def indexer
Expand All @@ -169,6 +173,10 @@ def file_path
File.expand_path(File.join(settings.data, *request.path_info))
end

def disk_cache
@disk_cache = Geminabox::DiskCache.new(File.join(settings.data, "_cache"))
end

def load_gems
@loaded_gems ||=
%w(specs prerelease_specs).inject(GemVersionCollection.new){|gems, specs_file_type|
Expand Down
39 changes: 39 additions & 0 deletions lib/geminabox/disk_cache.rb
@@ -0,0 +1,39 @@
require "fileutils"

class Geminabox::DiskCache
attr_reader :root_path

def initialize(root_path)
@root_path = root_path
ensure_dir_exists!
end

def flush
FileUtils.rm_rf(root_path)
ensure_dir_exists!
end

def cache(key)
key = Digest::MD5.hexdigest(key)
read(key) || write(key, yield)
end

def read(key)
path = File.join(root_path, key)
File.read(path) if File.exists?(path)
end

def write(key, value)
path = File.join(root_path, key)
File.open(path, 'wb'){|f|
f << value
}
value
end

protected

def ensure_dir_exists!
FileUtils.mkdir_p(root_path)
end
end
19 changes: 19 additions & 0 deletions test/integration/dependency_api/dependencies_api_test.rb
Expand Up @@ -37,6 +37,25 @@ class DependenciesApiTest < Geminabox::TestCase
assert_equal expected, deps
end

test "dependency cache is cleared as expected" do
assert_can_push(:a, :deps => [[:b, '>= 0']])

deps = fetch_deps("a")
expected = [
{:name=>"a", :number=>"1.0.0", :platform=>"ruby", :dependencies=>[["b", ">= 0"]]}
]
assert_equal expected, deps

assert_can_push(:a, :deps => [[:b, '>= 1']], :version => "2.0.0")

deps = fetch_deps("a")
expected = [
{:name=>"a", :number=>"1.0.0", :platform=>"ruby", :dependencies=>[["b", ">= 0"]]},
{:name=>"a", :number=>"2.0.0", :platform=>"ruby", :dependencies=>[["b", ">= 1"]]}
]
assert_equal expected, deps
end

protected
def fetch_deps(*gems)
Marshal.load HTTPClient.new.get_content(url_for("api/v1/dependencies?gems=#{gems.join(",")}"))
Expand Down
43 changes: 43 additions & 0 deletions test/units/disk_cache_test.rb
@@ -0,0 +1,43 @@
require 'test_helper'

class DiskCacheTest < MiniTest::Unit::TestCase
DIR = "/tmp/geminabox-disk-cache-test"
def setup
FileUtils.rm_rf(DIR)
end

def subject
@subject ||= Geminabox::DiskCache.new(DIR)
end

def test_cache_some_stuff
called = 0
callable = lambda{
subject.cache("foo") do
called += 1
"HELLO"
end
}
assert_equal "HELLO", callable.call
assert_equal "HELLO", callable.call
assert_equal 1, called
end

def test_flushing_the_cache
assert_equal "foo", subject.cache("foo"){ "foo" }
assert_equal "foo", subject.cache("foo"){ "bar" }

subject.flush

assert_equal "bar", subject.cache("foo"){ "bar" }
end

def test_multiple_keys
assert_equal "foo", subject.cache("foo"){ "foo" }
assert_equal "bar", subject.cache("bar"){ "bar" }
end

def teardown
FileUtils.rm_rf(DIR)
end
end

0 comments on commit 50dc3bb

Please sign in to comment.