api_cache 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/api_cache.gemspec +2 -2
- data/lib/api_cache.rb +4 -3
- data/lib/api_cache/api.rb +10 -6
- data/spec/api_spec.rb +11 -3
- data/spec/integration_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- metadata +3 -3
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.2.
|
6
|
+
s.version = "0.2.2"
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Martyn Loughran"]
|
9
9
|
s.email = ["me@mloughran.com"]
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
|
19
19
|
s.add_development_dependency('rspec', "~> 1.0")
|
20
|
-
s.add_development_dependency('
|
20
|
+
s.add_development_dependency('webmock')
|
21
21
|
s.add_development_dependency('rake')
|
22
22
|
s.add_development_dependency('moneta', "~> 0.6.0")
|
23
23
|
s.add_development_dependency('dalli')
|
data/lib/api_cache.rb
CHANGED
@@ -101,6 +101,7 @@ class APICache
|
|
101
101
|
cache_state = cache.state
|
102
102
|
|
103
103
|
if cache_state == :current
|
104
|
+
APICache.logger.debug "APICache #{@key}: Returning from cache"
|
104
105
|
cache.get
|
105
106
|
else
|
106
107
|
begin
|
@@ -108,15 +109,15 @@ class APICache
|
|
108
109
|
cache.set(value)
|
109
110
|
value
|
110
111
|
rescue => e
|
111
|
-
APICache.logger.info "
|
112
|
-
|
112
|
+
APICache.logger.info "APICache #{@key}: Exception raised (#{e.message} - #{e.class})" \
|
113
|
+
|
113
114
|
# No point outputting backgraces for internal APICache errors
|
114
115
|
APICache.logger.debug "Backtrace:\n#{e.backtrace.join("\n")}" unless e.kind_of?(APICacheError)
|
115
116
|
|
116
117
|
if cache_state == :refetch
|
117
118
|
cache.get
|
118
119
|
else
|
119
|
-
APICache.logger.warn "Data not available in the cache or from API
|
120
|
+
APICache.logger.warn "APICache #{@key}: Data not available in the cache or from API"
|
120
121
|
if options.has_key?(:fail)
|
121
122
|
fail = options[:fail]
|
122
123
|
fail.respond_to?(:call) ? fail.call : fail
|
data/lib/api_cache/api.rb
CHANGED
@@ -33,7 +33,7 @@ class APICache
|
|
33
33
|
#
|
34
34
|
def get
|
35
35
|
check_queryable!
|
36
|
-
APICache.logger.debug "
|
36
|
+
APICache.logger.debug "APICache #{@key}: Calling API"
|
37
37
|
set_queried_at
|
38
38
|
Timeout::timeout(@timeout) do
|
39
39
|
if @block
|
@@ -44,7 +44,7 @@ class APICache
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
rescue Timeout::Error => e
|
47
|
-
raise APICache::TimeoutError, "
|
47
|
+
raise APICache::TimeoutError, "APICache #{@key}: Request timed out (timeout #{@timeout}s)"
|
48
48
|
end
|
49
49
|
|
50
50
|
private
|
@@ -56,8 +56,12 @@ class APICache
|
|
56
56
|
# 2xx response code
|
57
57
|
response.body
|
58
58
|
else
|
59
|
-
raise APICache::InvalidResponse, "InvalidResponse http response: #{response.code}"
|
59
|
+
raise APICache::InvalidResponse, "APICache #{@key}: InvalidResponse http response: #{response.code}"
|
60
60
|
end
|
61
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
62
|
+
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
63
|
+
Net::ProtocolError, Errno::ECONNREFUSED, SocketError => e
|
64
|
+
raise APICache::InvalidResponse, "APICache #{@key}: Net::HTTP error (#{e.message} - #{e.class})"
|
61
65
|
end
|
62
66
|
|
63
67
|
def redirecting_get(url)
|
@@ -71,14 +75,14 @@ class APICache
|
|
71
75
|
def check_queryable!
|
72
76
|
if previously_queried?
|
73
77
|
if Time.now - queried_at > @period
|
74
|
-
APICache.logger.debug "
|
78
|
+
APICache.logger.debug "APICache #{@key}: Is queryable - retry_time has passed"
|
75
79
|
else
|
76
|
-
APICache.logger.debug "
|
80
|
+
APICache.logger.debug "APICache #{@key}: Not queryable - queried too recently"
|
77
81
|
raise APICache::CannotFetch,
|
78
82
|
"Cannot fetch #{@key}: queried too recently"
|
79
83
|
end
|
80
84
|
else
|
81
|
-
APICache.logger.debug "
|
85
|
+
APICache.logger.debug "APICache #{@key}: Is queryable - first query"
|
82
86
|
end
|
83
87
|
end
|
84
88
|
|
data/spec/api_spec.rb
CHANGED
@@ -2,9 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe APICache::API do
|
4
4
|
before :each do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
stub_request(:get, "http://www.google.com/").to_return(:body => "Google")
|
6
|
+
stub_request(:get, "http://froogle.google.com/").to_return(:status => 302, :headers => {:location => "http://products.google.com"})
|
7
|
+
stub_request(:get, "http://products.google.com/").to_return(:body => "Google Product Search")
|
8
8
|
|
9
9
|
@options = {
|
10
10
|
:period => 1,
|
@@ -41,6 +41,14 @@ describe APICache::API do
|
|
41
41
|
api.get.should =~ /Google Product Search/
|
42
42
|
end
|
43
43
|
|
44
|
+
it "should rescue errors thrown by Net::HTTP and raise APICache::InvalidResponse" do
|
45
|
+
stub_request(:get, "http://example.com/").to_raise(Errno::ECONNREFUSED)
|
46
|
+
api = APICache::API.new('http://example.com/', @options)
|
47
|
+
lambda {
|
48
|
+
api.get
|
49
|
+
}.should raise_error(APICache::InvalidResponse, "APICache http://example.com/: Net::HTTP error (Connection refused - Exception from WebMock - Errno::ECONNREFUSED)")
|
50
|
+
end
|
51
|
+
|
44
52
|
end
|
45
53
|
|
46
54
|
describe "with a block" do
|
data/spec/integration_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "api_cache" do
|
4
4
|
before :each do
|
5
|
-
|
5
|
+
stub_request(:get, "http://www.google.com/").to_return(:body => "Google")
|
6
6
|
|
7
7
|
APICache.store = nil
|
8
8
|
end
|
@@ -40,7 +40,7 @@ describe "api_cache" do
|
|
40
40
|
APICache.get('foo', :timeout => 1) do
|
41
41
|
sleep 1.1
|
42
42
|
end
|
43
|
-
}.should raise_error APICache::TimeoutError, '
|
43
|
+
}.should raise_error APICache::TimeoutError, 'APICache foo: Request timed out (timeout 1s)'
|
44
44
|
|
45
45
|
APICache.get('foo', :period => 0) do
|
46
46
|
'bar'
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: api_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Martyn Loughran
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-28 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
type: :development
|
26
26
|
version_requirements: *id001
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: webmock
|
29
29
|
prerelease: false
|
30
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|