Permalink
Browse files

Faster bundler API support.

  • Loading branch information...
1 parent 89a965a commit 50dc3bb67c153987295b68abe1ba33a3008731c8 @tomlea tomlea committed Mar 13, 2012
Showing with 125 additions and 11 deletions.
  1. +6 −1 Rakefile
  2. +18 −10 lib/geminabox.rb
  3. +39 −0 lib/geminabox/disk_cache.rb
  4. +19 −0 test/integration/dependency_api/dependencies_api_test.rb
  5. +43 −0 test/units/disk_cache_test.rb
View
7 Rakefile
@@ -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
View
28 lib/geminabox.rb
@@ -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}"
@@ -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
@@ -159,6 +162,7 @@ def reindex(force_rebuild = false)
reindex(:force_rebuild)
end
end
+ disk_cache.flush
end
def indexer
@@ -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|
View
39 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
View
19 test/integration/dependency_api/dependencies_api_test.rb
@@ -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(",")}"))
View
43 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.