api_cache 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -0
- data/README.md +2 -4
- data/Rakefile +2 -5
- data/api_cache.gemspec +3 -4
- data/lib/api_cache.rb +7 -0
- data/lib/api_cache/abstract_store.rb +18 -2
- data/lib/api_cache/cache.rb +5 -0
- data/lib/api_cache/dalli_store.rb +7 -3
- data/lib/api_cache/memory_store.rb +9 -11
- data/lib/api_cache/moneta_store.rb +7 -3
- data/lib/api_cache/null_store.rb +13 -6
- data/spec/api_cache_spec.rb +90 -57
- data/spec/cache_spec.rb +6 -0
- data/spec/dalli_store_spec.rb +3 -23
- data/spec/memory_store_spec.rb +10 -0
- data/spec/monteta_store_spec.rb +3 -24
- data/spec/null_store_spec.rb +1 -1
- data/spec/shared_store_specs.rb +42 -0
- data/spec/spec_helper.rb +3 -1
- metadata +86 -85
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 04d4fca20574868e21c48d50e07ae2d6cc78f493
|
4
|
+
data.tar.gz: a8b1f69f0a0fe9d9c5ee30a6fa5becffe3bcb4e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9df4d242de81e51b02398ca4781a18ae83460e3b059f14410d438334423928a533c7025fea819258d5a3fc1338b928ef3085092826cc6ea521b47d9645fc8189
|
7
|
+
data.tar.gz: 23e2d15510a671df5f6ca4d488890165785cce3df10ab67b12b4502d0f85bb456d17c9e706c717c3ae7db47226b4e9f4f726231c296c95ded2baab99a16b27d4
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 0.3.0 – 2014-07-16
|
4
|
+
|
5
|
+
* [NEW] Allow keys to be deleted [Doug Puchalski]
|
6
|
+
* [UPDATED] Updated Moneta dependency - works with 0.7.x & 0.8.x
|
7
|
+
* [FIX] Fixed long standing bug in the case that the `created_at` key was evicted before the data key (for example when using memcached)
|
data/README.md
CHANGED
@@ -16,8 +16,7 @@ APICache allows any API client library to be easily wrapped with a robust cachin
|
|
16
16
|
|
17
17
|
# Use a proper store
|
18
18
|
require 'moneta'
|
19
|
-
|
20
|
-
APICache.store = Moneta::Memcache.new(:server => "localhost")
|
19
|
+
APICache.store = Moneta.new(:Memcached)
|
21
20
|
|
22
21
|
# Wrap an API, and handle the failure case
|
23
22
|
|
@@ -94,8 +93,7 @@ You can send any of the following options to `APICache.get(url, options = {}, &b
|
|
94
93
|
|
95
94
|
Before using the APICache you should set the cache to use. By default an in memory hash is used - obviously not a great idea. Thankfully APICache can use any moneta store, so for example if you wanted to use memcache you'd do this:
|
96
95
|
|
97
|
-
|
98
|
-
APICache.store = Moneta::Memcache.new(:server => "localhost")
|
96
|
+
APICache.store = Moneta.new(:Memcached)
|
99
97
|
|
100
98
|
Please be liberal with the github issue tracker, more so with pull requests, or drop me a mail to me [at] mloughran [dot] com. I'd love to hear from you.
|
101
99
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
|
-
require '
|
5
|
-
|
6
|
-
t.libs << 'lib' << 'spec'
|
7
|
-
t.spec_files = FileList['spec/**/*_spec.rb']
|
8
|
-
end
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new
|
9
6
|
|
10
7
|
task :default => :spec
|
data/api_cache.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "api_cache"
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.3.0"
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Martyn Loughran"]
|
9
9
|
s.email = ["me@mloughran.com"]
|
@@ -16,10 +16,9 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
|
19
|
-
s.add_development_dependency('rspec', "~>
|
19
|
+
s.add_development_dependency('rspec', "~> 2.7")
|
20
20
|
s.add_development_dependency('webmock')
|
21
21
|
s.add_development_dependency('rake')
|
22
|
-
s.add_development_dependency('moneta', "~> 0.
|
22
|
+
s.add_development_dependency('moneta', "~> 0.7")
|
23
23
|
s.add_development_dependency('dalli')
|
24
|
-
s.add_development_dependency('memcache-client')
|
25
24
|
end
|
data/lib/api_cache.rb
CHANGED
@@ -14,14 +14,30 @@ class APICache
|
|
14
14
|
raise "Method not implemented. Called abstract class."
|
15
15
|
end
|
16
16
|
|
17
|
+
# Delete the given key. The return value is not used.
|
18
|
+
def delete(key)
|
19
|
+
raise "Method not implemented. Called abstract class."
|
20
|
+
end
|
21
|
+
|
17
22
|
# Does a given key exist in the cache?
|
18
23
|
def exists?(key)
|
19
24
|
raise "Method not implemented. Called abstract class."
|
20
25
|
end
|
21
26
|
|
22
|
-
#
|
23
|
-
def
|
27
|
+
# created_at returns the time when the key was last set
|
28
|
+
def created_at(key)
|
24
29
|
raise "Method not implemented. Called abstract class."
|
25
30
|
end
|
31
|
+
|
32
|
+
# expired? returns true if the given timeout has passed since the key was
|
33
|
+
# set. It has nothing to say about the existence or otherwise of said key.
|
34
|
+
def expired?(key, timeout)
|
35
|
+
if (created_at = created_at(key))
|
36
|
+
Time.now - created_at > timeout
|
37
|
+
else
|
38
|
+
# If the created_at data is missing assume expired
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
26
42
|
end
|
27
43
|
end
|
data/lib/api_cache/cache.rb
CHANGED
@@ -16,14 +16,18 @@ class APICache
|
|
16
16
|
@dalli.get(key)
|
17
17
|
end
|
18
18
|
|
19
|
+
# Delete value.
|
20
|
+
def delete(key)
|
21
|
+
@dalli.delete(key)
|
22
|
+
end
|
23
|
+
|
19
24
|
# Does a given key exist in the cache?
|
20
25
|
def exists?(key)
|
21
26
|
!get(key).nil?
|
22
27
|
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
Time.now - @dalli.get("#{key}_created_at") > timeout
|
29
|
+
def created_at(key)
|
30
|
+
@dalli.get("#{key}_created_at")
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class APICache
|
2
2
|
class MemoryStore < APICache::AbstractStore
|
3
|
-
def initialize
|
3
|
+
def initialize(cache = {})
|
4
4
|
APICache.logger.debug "Using memory store"
|
5
|
-
@cache =
|
5
|
+
@cache = cache
|
6
6
|
true
|
7
7
|
end
|
8
8
|
|
@@ -13,23 +13,21 @@ class APICache
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def get(key)
|
16
|
-
data = @cache[key][1]
|
16
|
+
data = exists?(key) ? @cache[key][1] : nil
|
17
17
|
APICache.logger.debug("cache: #{data.nil? ? "miss" : "hit"} (#{key})")
|
18
18
|
data
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
21
|
+
def delete(key)
|
22
|
+
@cache.delete(key)
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
|
25
|
+
def exists?(key)
|
26
|
+
!@cache[key].nil?
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
def created(key)
|
32
|
-
@cache[key][0]
|
29
|
+
def created_at(key)
|
30
|
+
@cache[key] && @cache[key][0]
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
@@ -16,14 +16,18 @@ class APICache
|
|
16
16
|
@moneta[key]
|
17
17
|
end
|
18
18
|
|
19
|
+
# Delete value.
|
20
|
+
def delete(key)
|
21
|
+
@moneta.delete(key)
|
22
|
+
end
|
23
|
+
|
19
24
|
# Does a given key exist in the cache?
|
20
25
|
def exists?(key)
|
21
26
|
@moneta.key?(key)
|
22
27
|
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
Time.now - @moneta["#{key}_created_at"] > timeout
|
29
|
+
def created_at(key)
|
30
|
+
@moneta["#{key}_created_at"]
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
data/lib/api_cache/null_store.rb
CHANGED
@@ -4,17 +4,24 @@ class APICache
|
|
4
4
|
class NullStore < APICache::AbstractStore
|
5
5
|
def initialize
|
6
6
|
end
|
7
|
-
|
8
|
-
def exists?(key)
|
9
|
-
false
|
10
|
-
end
|
11
7
|
|
12
8
|
def set(key, value)
|
13
9
|
true
|
14
10
|
end
|
15
11
|
|
16
|
-
def
|
17
|
-
|
12
|
+
def get(key)
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(key)
|
17
|
+
end
|
18
|
+
|
19
|
+
def exists?(key)
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def created_at(key)
|
24
|
+
nil
|
18
25
|
end
|
19
26
|
end
|
20
27
|
end
|
data/spec/api_cache_spec.rb
CHANGED
@@ -23,8 +23,7 @@ describe APICache do
|
|
23
23
|
|
24
24
|
it "should allow moneta instances to be passed" do
|
25
25
|
require 'moneta'
|
26
|
-
|
27
|
-
APICache.store = Moneta::Memory.new
|
26
|
+
APICache.store = Moneta.new(:Memory)
|
28
27
|
APICache.store.should be_kind_of(APICache::MonetaStore)
|
29
28
|
end
|
30
29
|
|
@@ -40,62 +39,96 @@ describe APICache do
|
|
40
39
|
end
|
41
40
|
|
42
41
|
describe "get method" do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
42
|
+
|
43
|
+
context "when cache is mocked" do
|
44
|
+
before :each do
|
45
|
+
@api = mock(APICache::API, :get => @api_data)
|
46
|
+
@cache = mock(APICache::Cache, :get => @cache_data, :set => true)
|
47
|
+
|
48
|
+
APICache::API.stub!(:new).and_return(@api)
|
49
|
+
APICache::Cache.stub!(:new).and_return(@cache)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should fetch data from the cache if the state is :current" do
|
53
|
+
@cache.stub!(:state).and_return(:current)
|
54
|
+
|
55
|
+
APICache.get(@key).should == @cache_data
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should make new request to API if the state is :refetch and store result in cache" do
|
59
|
+
@cache.stub!(:state).and_return(:refetch)
|
60
|
+
@cache.should_receive(:set).with(@api_data)
|
61
|
+
|
62
|
+
APICache.get(@key).should == @api_data
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return the cached value if the state is :refetch but the api is not accessible" do
|
66
|
+
@cache.stub!(:state).and_return(:refetch)
|
67
|
+
@api.should_receive(:get).with.and_raise(APICache::CannotFetch)
|
68
|
+
|
69
|
+
APICache.get(@key).should == @cache_data
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should make new request to API if the state is :invalid" do
|
73
|
+
@cache.stub!(:state).and_return(:invalid)
|
74
|
+
|
75
|
+
APICache.get(@key).should == @api_data
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should raise CannotFetch if the api cannot fetch data and the cache state is :invalid" do
|
79
|
+
@cache.stub!(:state).and_return(:invalid)
|
80
|
+
@api.should_receive(:get).with.and_raise(APICache::CannotFetch)
|
81
|
+
|
82
|
+
lambda {
|
83
|
+
APICache.get(@key).should
|
84
|
+
}.should raise_error(APICache::CannotFetch)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should make new request to API if the state is :missing" do
|
88
|
+
@cache.stub!(:state).and_return(:missing)
|
89
|
+
|
90
|
+
APICache.get(@key).should == @api_data
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should raise an exception if the api cannot fetch data and the cache state is :missing" do
|
94
|
+
@cache.stub!(:state).and_return(:missing)
|
95
|
+
@api.should_receive(:get).with.and_raise(APICache::CannotFetch)
|
96
|
+
|
97
|
+
lambda {
|
98
|
+
APICache.get(@key).should
|
99
|
+
}.should raise_error(APICache::CannotFetch)
|
100
|
+
end
|
90
101
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
APICache
|
98
|
-
|
102
|
+
|
103
|
+
|
104
|
+
context "when cache is not mocked" do
|
105
|
+
|
106
|
+
before :each do
|
107
|
+
APICache.store = APICache::MemoryStore.new
|
108
|
+
@api = mock(APICache::API, :get => @api_data)
|
109
|
+
APICache::API.stub!(:new).and_return(@api)
|
110
|
+
end
|
111
|
+
|
112
|
+
#it "should initially fetch" do
|
113
|
+
# @api.should_receive(:get)
|
114
|
+
# APICache.get(@key)
|
115
|
+
#end
|
116
|
+
|
117
|
+
it "should only fetch once" do
|
118
|
+
@api.should_receive(:get).once
|
119
|
+
APICache.get(@key)
|
120
|
+
APICache.get(@key)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should refetch if deleted" do
|
124
|
+
@api.should_receive(:get).twice
|
125
|
+
APICache.get(@key)
|
126
|
+
APICache.delete(@key)
|
127
|
+
APICache.get(@key)
|
128
|
+
end
|
129
|
+
|
99
130
|
end
|
131
|
+
|
100
132
|
end
|
133
|
+
|
101
134
|
end
|
data/spec/cache_spec.rb
CHANGED
data/spec/dalli_store_spec.rb
CHANGED
@@ -3,28 +3,8 @@ require 'spec_helper'
|
|
3
3
|
require 'dalli'
|
4
4
|
|
5
5
|
describe APICache::DalliStore do
|
6
|
-
|
7
|
-
|
8
|
-
@dalli.delete('foo')
|
9
|
-
@store = APICache::DalliStore.new(@dalli)
|
10
|
-
end
|
6
|
+
let(:cache) { Dalli::Client.new("localhost:11211") }
|
7
|
+
let(:store) { APICache::DalliStore.new(cache) }
|
11
8
|
|
12
|
-
|
13
|
-
@store.set('key', 'value')
|
14
|
-
@store.get('key').should == 'value'
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should allow checking whether a key exists' do
|
18
|
-
@store.exists?('foo').should be_false
|
19
|
-
@store.set('foo', 'bar')
|
20
|
-
@store.exists?('foo').should be_true
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should allow checking whether a given amount of time has passed since the key was set' do
|
24
|
-
@store.expired?('foo', 1).should be_false
|
25
|
-
@store.set('foo', 'bar')
|
26
|
-
@store.expired?('foo', 1).should be_false
|
27
|
-
sleep 1
|
28
|
-
@store.expired?('foo', 1).should be_true
|
29
|
-
end
|
9
|
+
include_examples "generic store"
|
30
10
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe APICache::MemoryStore do
|
4
|
+
let(:cache) { {} }
|
5
|
+
let(:store) { APICache::MemoryStore.new(cache) }
|
6
|
+
|
7
|
+
# Deleting created_at makes no sense given the way MemoryStore stores data
|
8
|
+
@skip_created_at_deletion = true
|
9
|
+
include_examples "generic store"
|
10
|
+
end
|
data/spec/monteta_store_spec.rb
CHANGED
@@ -1,31 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
require 'moneta'
|
4
|
-
require 'moneta/memcache'
|
5
4
|
|
6
5
|
describe APICache::MonetaStore do
|
7
|
-
|
8
|
-
|
9
|
-
@moneta.delete('foo')
|
10
|
-
@store = APICache::MonetaStore.new(@moneta)
|
11
|
-
end
|
6
|
+
let(:cache) { Moneta.new(:Memcached) }
|
7
|
+
let(:store) { APICache::MonetaStore.new(cache) }
|
12
8
|
|
13
|
-
|
14
|
-
@store.set("key", "value")
|
15
|
-
@store.get("key").should == "value"
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should allow checking whether a key exists" do
|
19
|
-
@store.exists?('foo').should be_false
|
20
|
-
@store.set('foo', 'bar')
|
21
|
-
@store.exists?('foo').should be_true
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should allow checking whether a given amount of time has passed since the key was set" do
|
25
|
-
@store.expired?('foo', 1).should be_false
|
26
|
-
@store.set('foo', 'bar')
|
27
|
-
@store.expired?('foo', 1).should be_false
|
28
|
-
sleep 1
|
29
|
-
@store.expired?('foo', 1).should be_true
|
30
|
-
end
|
9
|
+
include_examples "generic store"
|
31
10
|
end
|
data/spec/null_store_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe APICache::NullStore do
|
|
11
11
|
@store.exists?('foo').should be_false
|
12
12
|
end
|
13
13
|
|
14
|
-
it "should
|
14
|
+
it "should always say keys are expired" do
|
15
15
|
@store.expired?('foo', 1).should be_true
|
16
16
|
@store.set('foo', 'bar')
|
17
17
|
@store.expired?('foo', 1).should be_true
|
@@ -0,0 +1,42 @@
|
|
1
|
+
shared_examples "generic store" do
|
2
|
+
before :each do
|
3
|
+
cache.delete("foo")
|
4
|
+
end
|
5
|
+
|
6
|
+
it "should allow set and get" do
|
7
|
+
store.set("foo", "bar")
|
8
|
+
store.get("foo").should == "bar"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should report existence" do
|
12
|
+
store.exists?("foo").should == false
|
13
|
+
store.set("foo", "bar")
|
14
|
+
store.exists?("foo").should == true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow checking expiration" do
|
18
|
+
store.set("foo", "bar")
|
19
|
+
store.expired?("foo", 1).should == false
|
20
|
+
store.expired?("foo", 0).should == true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return nil if not found" do
|
24
|
+
store.get("nothing").should == nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be possible to delete" do
|
28
|
+
store.set("foo", "bar")
|
29
|
+
store.delete("key")
|
30
|
+
store.exists?("key").should == false
|
31
|
+
store.get("key").should == nil
|
32
|
+
end
|
33
|
+
|
34
|
+
unless @skip_created_at_deletion
|
35
|
+
it "should claim that key has expired if _created_at key is missing" do
|
36
|
+
store.set("key", "bar")
|
37
|
+
store.expired?("foo", 10).should == false
|
38
|
+
cache.delete("foo_created_at")
|
39
|
+
store.expired?("foo", 10).should == true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,95 +1,97 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_cache
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.2.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Martyn Loughran
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2014-07-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
17
14
|
name: rspec
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: "1.0"
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.7'
|
25
20
|
type: :development
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: webmock
|
29
21
|
prerelease: false
|
30
|
-
|
31
|
-
|
32
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: webmock
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
33
31
|
- - ">="
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
36
34
|
type: :development
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: rake
|
40
35
|
prerelease: false
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
44
45
|
- - ">="
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
47
48
|
type: :development
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: moneta
|
51
49
|
prerelease: false
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: moneta
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.7'
|
58
62
|
type: :development
|
59
|
-
version_requirements: *id004
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: dalli
|
62
63
|
prerelease: false
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.7'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dalli
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
66
73
|
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version:
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
69
76
|
type: :development
|
70
|
-
version_requirements: *id005
|
71
|
-
- !ruby/object:Gem::Dependency
|
72
|
-
name: memcache-client
|
73
77
|
prerelease: false
|
74
|
-
|
75
|
-
|
76
|
-
requirements:
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
77
80
|
- - ">="
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version:
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: APICache allows any API client library to be easily wrapped with a robust
|
84
|
+
caching layer. It supports caching (obviously), serving stale data and limits on
|
85
|
+
the number of API calls. It's also got a handy syntax if all you want to do is cache
|
86
|
+
a bothersome url.
|
87
|
+
email:
|
84
88
|
- me@mloughran.com
|
85
89
|
executables: []
|
86
|
-
|
87
90
|
extensions: []
|
88
|
-
|
89
91
|
extra_rdoc_files: []
|
90
|
-
|
91
|
-
|
92
|
-
- .
|
92
|
+
files:
|
93
|
+
- ".gitignore"
|
94
|
+
- CHANGELOG.md
|
93
95
|
- Gemfile
|
94
96
|
- LICENSE
|
95
97
|
- README.md
|
@@ -110,43 +112,42 @@ files:
|
|
110
112
|
- spec/cache_spec.rb
|
111
113
|
- spec/dalli_store_spec.rb
|
112
114
|
- spec/integration_spec.rb
|
115
|
+
- spec/memory_store_spec.rb
|
113
116
|
- spec/monteta_store_spec.rb
|
114
117
|
- spec/null_store_spec.rb
|
118
|
+
- spec/shared_store_specs.rb
|
115
119
|
- spec/spec_helper.rb
|
116
|
-
has_rdoc: true
|
117
120
|
homepage: http://mloughran.github.com/api_cache/
|
118
121
|
licenses: []
|
119
|
-
|
122
|
+
metadata: {}
|
120
123
|
post_install_message:
|
121
124
|
rdoc_options: []
|
122
|
-
|
123
|
-
require_paths:
|
125
|
+
require_paths:
|
124
126
|
- lib
|
125
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
-
|
127
|
-
requirements:
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
128
129
|
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version:
|
131
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
-
|
133
|
-
requirements:
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
134
|
- - ">="
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version:
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
137
|
requirements: []
|
138
|
-
|
139
138
|
rubyforge_project:
|
140
|
-
rubygems_version:
|
139
|
+
rubygems_version: 2.2.2
|
141
140
|
signing_key:
|
142
|
-
specification_version:
|
141
|
+
specification_version: 4
|
143
142
|
summary: API Cache allows advanced caching of APIs
|
144
|
-
test_files:
|
143
|
+
test_files:
|
145
144
|
- spec/api_cache_spec.rb
|
146
145
|
- spec/api_spec.rb
|
147
146
|
- spec/cache_spec.rb
|
148
147
|
- spec/dalli_store_spec.rb
|
149
148
|
- spec/integration_spec.rb
|
149
|
+
- spec/memory_store_spec.rb
|
150
150
|
- spec/monteta_store_spec.rb
|
151
151
|
- spec/null_store_spec.rb
|
152
|
+
- spec/shared_store_specs.rb
|
152
153
|
- spec/spec_helper.rb
|