rattlecache 0.2 → 0.3
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.
- data/lib/backends/filesystem.rb +5 -0
- data/lib/caches/Auctionscache.rb +14 -8
- data/lib/caches/Fieldsrequestcache.rb +13 -7
- data/lib/rattlecache.rb +48 -14
- data/rattlecache.gemspec +1 -1
- data/test/test_Backend_Filesystem.rb +2 -2
- metadata +29 -47
data/lib/backends/filesystem.rb
CHANGED
data/lib/caches/Auctionscache.rb
CHANGED
@@ -19,9 +19,9 @@ module Rattlecache
|
|
19
19
|
# If yes, request without fields and look into ['lastModified']
|
20
20
|
# if we need to fetch new or answer with our cached result.",
|
21
21
|
if cached_data[:status] == 200
|
22
|
-
puts "Debug: Auctionscache: cache HIT for #{url}"
|
22
|
+
#puts "Debug: Auctionscache: cache HIT for #{url}"
|
23
23
|
unless is_lmt_and_url_request(url)
|
24
|
-
puts "Debug: Auctionscache: has fields. Timethings: #{cached_data[:lastModified]} < #{get_lmt(url,header)} #{cached_data[:lastModified] < get_lmt(url,header)}"
|
24
|
+
#puts "Debug: Auctionscache: has fields. Timethings: #{cached_data[:lastModified]} < #{get_lmt(url,header)} #{cached_data[:lastModified] < get_lmt(url,header)}"
|
25
25
|
if cached_data[:lastModified] < get_lmt(url,header)
|
26
26
|
cached_data = {:status => 404}
|
27
27
|
end
|
@@ -33,7 +33,7 @@ module Rattlecache
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
else
|
36
|
-
puts "Debug: Auctionscache: cache MISS for #{url}"
|
36
|
+
#puts "Debug: Auctionscache: cache MISS for #{url}"
|
37
37
|
end
|
38
38
|
cached_data
|
39
39
|
end
|
@@ -49,7 +49,7 @@ module Rattlecache
|
|
49
49
|
# @param header [Hash] the Hash of headers for a api request
|
50
50
|
def get_lmt(url,header)
|
51
51
|
cached_data = @backend.get(sanitize(generic_auctions_url(url)))
|
52
|
-
puts "Debug: get_lmt() cache result for generic url: #{cached_data[:status]}"
|
52
|
+
#puts "Debug: get_lmt() cache result for generic url: #{cached_data[:status]}"
|
53
53
|
# if the object was not in the cache or it is expired
|
54
54
|
if cached_data[:status] != 200 or generic_needs_request?(cached_data[:header],cached_data[:lastModified])
|
55
55
|
# request it from the api
|
@@ -58,21 +58,27 @@ module Rattlecache
|
|
58
58
|
cached_data = @backend.get(sanitize(generic_auctions_url(url)))
|
59
59
|
end
|
60
60
|
# this a JS milliseconds timestamp, we only do seconds!
|
61
|
-
Time.at(JSON.parse(cached_data[:object])["lastModified"]/1000)
|
61
|
+
Time.at(JSON.parse(cached_data[:object])["files"][0]["lastModified"]/1000)
|
62
62
|
end
|
63
63
|
|
64
64
|
def request_generic(url,header)
|
65
65
|
# need to request the generic guild response
|
66
66
|
url = generic_auctions_url(url)
|
67
67
|
# request it from the API:
|
68
|
-
|
69
|
-
|
68
|
+
begin
|
69
|
+
got = request_raw(url,header)
|
70
|
+
# FIXME this doesnt count towards the caches post count!
|
71
|
+
@backend.post({:key => sanitize(url),:header => got.header.to_hash, :data => got.body}) # and put into cache
|
72
|
+
rescue
|
73
|
+
# some day this will fail! Not sure yet what to do about...
|
74
|
+
raise
|
75
|
+
end
|
70
76
|
end
|
71
77
|
|
72
78
|
|
73
79
|
def generic_auctions_url(url)
|
74
80
|
u = URI.parse(url)
|
75
|
-
u.path=(u.path.gsub("-data","/data").gsub(/\/auctions.*\.json$/,""))
|
81
|
+
u.path=("/api/wow/"+u.path.gsub("-data","/data").gsub(/\/auctions.*\.json$/,""))
|
76
82
|
u.to_s
|
77
83
|
end
|
78
84
|
end
|
@@ -19,9 +19,9 @@ module Rattlecache
|
|
19
19
|
# If yes, request without fields and look into ['lastModified']
|
20
20
|
# if we need to fetch new or answer with our cached result.",
|
21
21
|
if cached_data[:status] == 200
|
22
|
-
puts "Debug: guildcache: cache HIT for #{url}"
|
22
|
+
#puts "Debug: guildcache: cache HIT for #{url}"
|
23
23
|
if has_fields?(url)
|
24
|
-
puts "Debug: guildcache: has fields. Timethings: #{cached_data[:lastModified]} < #{get_lmt(url,header)} #{cached_data[:lastModified] < get_lmt(url,header)}"
|
24
|
+
#puts "Debug: guildcache: has fields. Timethings: #{cached_data[:lastModified]} < #{get_lmt(url,header)} #{cached_data[:lastModified] < get_lmt(url,header)}"
|
25
25
|
if cached_data[:lastModified] < get_lmt(url,header)
|
26
26
|
cached_data = {:status => 404}
|
27
27
|
end
|
@@ -33,7 +33,7 @@ module Rattlecache
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
else
|
36
|
-
puts "Debug: guildcache: cache MISS for #{url}"
|
36
|
+
#puts "Debug: guildcache: cache MISS for #{url}"
|
37
37
|
end
|
38
38
|
cached_data
|
39
39
|
end
|
@@ -43,7 +43,7 @@ module Rattlecache
|
|
43
43
|
# @param header [Hash] the Hash of headers for a api request
|
44
44
|
def get_lmt(url,header)
|
45
45
|
cached_data = @backend.get(sanitize(url_without_fields(url)))
|
46
|
-
puts "Debug: get_lmt() cache result for generic url: #{cached_data[:status]}"
|
46
|
+
#puts "Debug: get_lmt() cache result for generic url: #{cached_data[:status]}"
|
47
47
|
# if the object was not in the cache or it is expired
|
48
48
|
if cached_data[:status] != 200 or generic_needs_request?(cached_data[:header],cached_data[:lastModified])
|
49
49
|
# request it from the api
|
@@ -51,8 +51,13 @@ module Rattlecache
|
|
51
51
|
# and load the new object
|
52
52
|
cached_data = @backend.get(sanitize(url_without_fields(url)))
|
53
53
|
end
|
54
|
-
|
55
|
-
|
54
|
+
begin
|
55
|
+
# this a JS milliseconds timestamp, we only do seconds!
|
56
|
+
Time.at(JSON.parse(cached_data[:object])["lastModified"]/1000)
|
57
|
+
rescue NoMethodError
|
58
|
+
# if the data could not be retrieved, there will be a noMethod on nil object Error!
|
59
|
+
raise
|
60
|
+
end
|
56
61
|
end
|
57
62
|
|
58
63
|
def request_without_fields(url,header)
|
@@ -60,11 +65,12 @@ module Rattlecache
|
|
60
65
|
url = url_without_fields(url)
|
61
66
|
# request it from the API:
|
62
67
|
got = request_raw(url,header)
|
68
|
+
# FIXME this doesnt count towards the caches post count!
|
63
69
|
@backend.post({:key => sanitize(url),:header => got.header.to_hash, :data => got.body}) # and put into cache
|
64
70
|
end
|
65
71
|
|
66
72
|
def url_without_fields(url)
|
67
|
-
url_obj = URI.parse(url)
|
73
|
+
url_obj = URI.parse(URI.encode(url))
|
68
74
|
url_obj.query=(url_obj.query.gsub(/fields=.+&|$/,"")) # strip the fields
|
69
75
|
url_obj.to_s
|
70
76
|
end
|
data/lib/rattlecache.rb
CHANGED
@@ -9,9 +9,13 @@ module Rattlecache
|
|
9
9
|
# @param backend [Symbol]
|
10
10
|
# @param adapter [Battlenet::Adapter::AbstractAdapter]
|
11
11
|
def initialize(backend = :filesystem, adapter = nil)
|
12
|
-
puts "Debug: rattlecache adapter: #{adapter}"
|
13
12
|
@adapter = adapter
|
14
13
|
@backend = Rattlecache::Backend.fetch(backend)
|
14
|
+
|
15
|
+
@status = Hash.new
|
16
|
+
@status[:hits] = 0
|
17
|
+
@status[:misses] = 0
|
18
|
+
@status[:posts] = 0
|
15
19
|
end
|
16
20
|
|
17
21
|
@request_pragmas = {
|
@@ -31,25 +35,27 @@ module Rattlecache
|
|
31
35
|
# what to do with this request?
|
32
36
|
case request_type(url)
|
33
37
|
when "guild"
|
34
|
-
puts "Debug: its a guild related request!"
|
35
38
|
require 'caches/Fieldsrequestcache'
|
36
|
-
Rattlecache::Fieldsrequestcache.new(@backend,@adapter).get(url,header)
|
39
|
+
res = Rattlecache::Fieldsrequestcache.new(@backend,@adapter).get(url,header)
|
37
40
|
when "character"
|
38
|
-
puts "Debug: its a character related request!"
|
39
41
|
require 'caches/Fieldsrequestcache'
|
40
|
-
Rattlecache::Fieldsrequestcache.new(@backend,@adapter).get(url,header)
|
42
|
+
res = Rattlecache::Fieldsrequestcache.new(@backend,@adapter).get(url,header)
|
41
43
|
when /auction.*/
|
42
|
-
puts "Debug: its a auchtion related request!"
|
43
44
|
require 'caches/Auctionscache'
|
44
|
-
Rattlecache::Auctionscache.new(@backend,@adapter).get(url,header)
|
45
|
+
res = Rattlecache::Auctionscache.new(@backend,@adapter).get(url,header)
|
45
46
|
when "item"
|
46
47
|
# for items it seems reasonable to cache them at least for a week
|
47
48
|
# a week in seconds: 60*60*24*7 = 604800
|
48
|
-
check_and_return(@backend.get(sanitize(url)),604800)
|
49
|
+
res = check_and_return(@backend.get(sanitize(url)),604800)
|
49
50
|
else
|
50
|
-
|
51
|
-
|
51
|
+
res = check_and_return(@backend.get(sanitize(url)))
|
52
|
+
end
|
53
|
+
if res[:status] == 200
|
54
|
+
@status[:hits] +=1
|
55
|
+
else
|
56
|
+
@status[:misses] +=1
|
52
57
|
end
|
58
|
+
res
|
53
59
|
end
|
54
60
|
|
55
61
|
def check_and_return(backend_result,given_time = nil)
|
@@ -67,6 +73,7 @@ module Rattlecache
|
|
67
73
|
|
68
74
|
# @param object [Hash]
|
69
75
|
def post(object)
|
76
|
+
@status[:posts] += 1
|
70
77
|
#puts "Cache class puts: #{object[:key]}"
|
71
78
|
@backend.post({:key => sanitize(object[:key]), :header => object[:header], :data => object[:data]})
|
72
79
|
end
|
@@ -82,7 +89,7 @@ module Rattlecache
|
|
82
89
|
# @param headerline [Hash]
|
83
90
|
# @param mtime [Time]
|
84
91
|
# @return [TrueClass|FalseClass]
|
85
|
-
def generic_needs_request?(headerline,mtime)
|
92
|
+
def generic_needs_request?(headerline,mtime,alternative_living_time = 3600)
|
86
93
|
header = JSON.parse(headerline)
|
87
94
|
#header["date"][0] is a String with CGI.rfc1123_date() encoded time,
|
88
95
|
# as there is no easy method to inverse this coding, I will keep using the files mtime
|
@@ -95,7 +102,7 @@ module Rattlecache
|
|
95
102
|
else
|
96
103
|
# if we dont find any hint, pull it again!
|
97
104
|
puts "Warning: Cache couldn't find any hint if this object is still valid!"
|
98
|
-
|
105
|
+
mtime+alternative_living_time < Time.now()
|
99
106
|
end
|
100
107
|
end
|
101
108
|
end
|
@@ -108,7 +115,7 @@ module Rattlecache
|
|
108
115
|
# @return [String]
|
109
116
|
def sanitize(objectKey)
|
110
117
|
# strip scheme, sort paramters and encode for safty
|
111
|
-
urlObj = URI.parse(objectKey)
|
118
|
+
urlObj = URI.parse(URI.encode(objectKey))
|
112
119
|
key = urlObj.host
|
113
120
|
key << urlObj.path
|
114
121
|
key << sort_params(urlObj.query)
|
@@ -134,7 +141,7 @@ module Rattlecache
|
|
134
141
|
# @return [String]
|
135
142
|
def request_type(objectKey)
|
136
143
|
#[0] = "". [1]= "api". [2]="wow", [3]= what we want
|
137
|
-
URI.parse(objectKey).path.split("/")[3]
|
144
|
+
URI.parse(URI.encode(objectKey)).path.split("/")[3]
|
138
145
|
end
|
139
146
|
|
140
147
|
# @param query [String]
|
@@ -151,5 +158,32 @@ module Rattlecache
|
|
151
158
|
req.get(url,header)
|
152
159
|
end
|
153
160
|
|
161
|
+
def status(options = {})
|
162
|
+
puts "Rattlecache: STATUS:"
|
163
|
+
puts "\tentries in cache: #{entries()}"
|
164
|
+
begin
|
165
|
+
puts "\trequests served: #{(hits+misses)}, hits: #{hits()} (#{(100*(hits()/(hits()+misses()))).to_i}%), misses: #{misses()} (#{(100*(misses()/(hits()+misses()))).to_i}%)"
|
166
|
+
rescue ZeroDivisionError
|
167
|
+
puts "\t requests served: nothing yet"
|
168
|
+
end
|
169
|
+
puts "\tposts to cache: #{posts}"
|
170
|
+
end
|
171
|
+
|
172
|
+
def entries()
|
173
|
+
@backend.entries()
|
174
|
+
end
|
175
|
+
|
176
|
+
def hits()
|
177
|
+
@status[:hits]
|
178
|
+
end
|
179
|
+
|
180
|
+
def misses()
|
181
|
+
@status[:misses]
|
182
|
+
end
|
183
|
+
|
184
|
+
def posts()
|
185
|
+
@status[:posts]
|
186
|
+
end
|
187
|
+
|
154
188
|
end
|
155
189
|
end
|
data/rattlecache.gemspec
CHANGED
@@ -66,8 +66,8 @@ class MyTest < Test::Unit::TestCase
|
|
66
66
|
@cache.post(testobject)
|
67
67
|
res = @cache.get(testobject[:key])
|
68
68
|
assert_instance_of(Hash,res)
|
69
|
-
# assert that this is
|
70
|
-
assert_equal(
|
69
|
+
# assert that this is 200, cause the object has no validation information
|
70
|
+
assert_equal(200,res[:status])
|
71
71
|
|
72
72
|
testobject[:header] = {
|
73
73
|
"foo" => ["bar-thishastobethere-baz"],
|
metadata
CHANGED
@@ -1,43 +1,33 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rattlecache
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 2
|
8
|
-
version: "0.2"
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.3'
|
5
|
+
prerelease:
|
9
6
|
platform: ruby
|
10
|
-
authors:
|
7
|
+
authors:
|
11
8
|
- Marv Cool
|
12
9
|
autorequire:
|
13
10
|
bindir: bin
|
14
11
|
cert_chain: []
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
dependencies:
|
19
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-08-25 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
20
15
|
name: rspec
|
21
|
-
|
22
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70146636750420 !ruby/object:Gem::Requirement
|
23
17
|
none: false
|
24
|
-
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
|
28
|
-
- 0
|
29
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
30
22
|
type: :development
|
31
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70146636750420
|
32
25
|
description:
|
33
26
|
email: marv@hostin.is
|
34
27
|
executables: []
|
35
|
-
|
36
28
|
extensions: []
|
37
|
-
|
38
29
|
extra_rdoc_files: []
|
39
|
-
|
40
|
-
files:
|
30
|
+
files:
|
41
31
|
- .gemtest
|
42
32
|
- .gitignore
|
43
33
|
- Gemfile
|
@@ -52,38 +42,30 @@ files:
|
|
52
42
|
- rattlecache.gemspec
|
53
43
|
- test/test_Backend_Filesystem.rb
|
54
44
|
- test/test_cache.rb
|
55
|
-
has_rdoc: true
|
56
45
|
homepage: https://github.com/MrMarvin/rattlcache/wiki
|
57
46
|
licenses: []
|
58
|
-
|
59
47
|
post_install_message:
|
60
48
|
rdoc_options: []
|
61
|
-
|
62
|
-
require_paths:
|
49
|
+
require_paths:
|
63
50
|
- lib
|
64
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
52
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
70
|
-
|
71
|
-
version: "0"
|
72
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
58
|
none: false
|
74
|
-
requirements:
|
75
|
-
- -
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
- 0
|
79
|
-
version: "0"
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
80
63
|
requirements: []
|
81
|
-
|
82
64
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.
|
65
|
+
rubygems_version: 1.8.9
|
84
66
|
signing_key:
|
85
67
|
specification_version: 3
|
86
68
|
summary: A smart caching system for battlenet API Requests.
|
87
|
-
test_files:
|
69
|
+
test_files:
|
88
70
|
- test/test_Backend_Filesystem.rb
|
89
71
|
- test/test_cache.rb
|