rattlecache 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -69,6 +69,11 @@ module Rattlecache
69
69
  end
70
70
  end
71
71
 
72
+ # returns the number of entries in this cache
73
+ def entries()
74
+ Dir.entries(@prefix).size - 2
75
+ end
76
+
72
77
  end
73
78
  end
74
79
  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: 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
- got = request_raw(url,header)
69
- @backend.post({:key => sanitize(url),:header => got.header.to_hash, :data => got.body}) # and put into cache
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
- # this a JS milliseconds timestamp, we only do seconds!
55
- Time.at(JSON.parse(cached_data[:object])["lastModified"]/1000)
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
@@ -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
- puts "Debug: its a boring request!"
51
- check_and_return(@backend.get(sanitize(url)))
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
- true
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
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "rattlecache"
6
- s.version = "0.2"
6
+ s.version = "0.3"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Marv Cool"]
9
9
  s.email = "marv@hostin.is"
@@ -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 404, cause the object has no validation information
70
- assert_equal(404,res[:status])
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
- prerelease: false
5
- segments:
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
- date: 2011-08-23 00:00:00 +02:00
17
- default_executable:
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
- prerelease: false
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
- segments:
28
- - 0
29
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
30
22
  type: :development
31
- version_requirements: *id001
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
- segments:
70
- - 0
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
- segments:
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.3.7
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