cacher 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +7 -0
- data/cacher.gemspec +15 -0
- data/lib/cacher.rb +158 -0
- data/lib/cacher/version.rb +5 -0
- metadata +49 -0
data/Gemfile
ADDED
data/cacher.gemspec
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require './lib/cacher/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "cacher"
|
5
|
+
s.version = Cacher.version
|
6
|
+
s.authors = ["Jay Adkisson"]
|
7
|
+
s.email = ["jay@goodguide.com"]
|
8
|
+
s.summary = "All your cache are belong to us"
|
9
|
+
s.description = "A nifty configurable frontend to any cache"
|
10
|
+
s.homepage = "http://github.com/jayferd/cacher"
|
11
|
+
s.rubyforge_project = "cacher"
|
12
|
+
s.files = Dir['Gemfile', 'cacher.gemspec', 'lib/**/*.rb']
|
13
|
+
|
14
|
+
# no dependencies
|
15
|
+
end
|
data/lib/cacher.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
require File.expand_path('cacher/version', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
module Cacher
|
6
|
+
extend self
|
7
|
+
|
8
|
+
class Base
|
9
|
+
include Cacher
|
10
|
+
end
|
11
|
+
|
12
|
+
#### configuration methods ####
|
13
|
+
attr_reader :options
|
14
|
+
def initialize(opts={})
|
15
|
+
opts.each do |k, v|
|
16
|
+
send(:"#{k}=", v)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_writer :cache
|
21
|
+
def cache
|
22
|
+
@cache ||= Rails.cache
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_accessor :namespace
|
26
|
+
def namespaced?
|
27
|
+
!!namespace
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_writer :max_key_size
|
31
|
+
def max_key_size
|
32
|
+
@max_key_size ||= 100
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_writer :marshal
|
36
|
+
def marshal?
|
37
|
+
return @marshal if instance_variable_defined? :@marshal
|
38
|
+
|
39
|
+
# default to false because Rails.cache handles marshalling for us
|
40
|
+
@marshal = false
|
41
|
+
end
|
42
|
+
|
43
|
+
def enabled?
|
44
|
+
return @enabled if instance_variable_defined? :@enabled
|
45
|
+
@enabled = false
|
46
|
+
end
|
47
|
+
|
48
|
+
def enable!
|
49
|
+
@enabled = true
|
50
|
+
end
|
51
|
+
|
52
|
+
def disable!
|
53
|
+
@enabled = false
|
54
|
+
end
|
55
|
+
|
56
|
+
#### core api ####
|
57
|
+
def key?(key)
|
58
|
+
return false unless enabled?
|
59
|
+
|
60
|
+
!!cache_get(key)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get(key, options={}, &blk)
|
64
|
+
return set(key, options, &blk) if options.delete(:break)
|
65
|
+
|
66
|
+
cached = cache_get(key)
|
67
|
+
|
68
|
+
if cached.nil?
|
69
|
+
return blk && set(key, options, &blk)
|
70
|
+
end
|
71
|
+
|
72
|
+
unmarshal_value(cached)
|
73
|
+
end
|
74
|
+
|
75
|
+
def set(key, options={}, &blk)
|
76
|
+
val = do_block(&blk)
|
77
|
+
cache_set(key, marshal_value(val))
|
78
|
+
val
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def decorate_key(key)
|
83
|
+
if namespaced?
|
84
|
+
key = "#{namespace}/#{key}"
|
85
|
+
end
|
86
|
+
|
87
|
+
key += "/marshal" if marshal?
|
88
|
+
|
89
|
+
key
|
90
|
+
end
|
91
|
+
|
92
|
+
def prepare_key(key)
|
93
|
+
decorated = decorate_key(key)
|
94
|
+
|
95
|
+
if decorated.size > max_key_size
|
96
|
+
decorated = decorate_key("sha1/#{Digest::SHA1.hexdigest(key)}")
|
97
|
+
end
|
98
|
+
|
99
|
+
decorated
|
100
|
+
end
|
101
|
+
|
102
|
+
def cache_get(key)
|
103
|
+
return nil unless enabled?
|
104
|
+
|
105
|
+
key = prepare_key(key)
|
106
|
+
|
107
|
+
if cache.respond_to? :get
|
108
|
+
cache.get(key)
|
109
|
+
else
|
110
|
+
cache.read(key)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def cache_set(key, val)
|
115
|
+
return val unless enabled?
|
116
|
+
|
117
|
+
key = prepare_key(key)
|
118
|
+
|
119
|
+
if cache.respond_to? :set
|
120
|
+
cache.set(key, val)
|
121
|
+
else
|
122
|
+
cache.write(key, val)
|
123
|
+
end
|
124
|
+
|
125
|
+
val
|
126
|
+
end
|
127
|
+
|
128
|
+
def do_block(&block)
|
129
|
+
return nil unless block_given?
|
130
|
+
|
131
|
+
if block.arity > 0
|
132
|
+
response = {}
|
133
|
+
block.call(response)
|
134
|
+
response
|
135
|
+
else
|
136
|
+
block.call
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
CACHER_NIL = 'cacher/nil'
|
141
|
+
def marshal_value(val)
|
142
|
+
if marshal?
|
143
|
+
Marshal.dump(val)
|
144
|
+
else
|
145
|
+
return CACHER_NIL if val.nil?
|
146
|
+
val
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def unmarshal_value(val)
|
151
|
+
if marshal?
|
152
|
+
Marshal.load(val)
|
153
|
+
else
|
154
|
+
return nil if val == CACHER_NIL
|
155
|
+
val
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cacher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jay Adkisson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-26 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: A nifty configurable frontend to any cache
|
15
|
+
email:
|
16
|
+
- jay@goodguide.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- Gemfile
|
22
|
+
- cacher.gemspec
|
23
|
+
- lib/cacher/version.rb
|
24
|
+
- lib/cacher.rb
|
25
|
+
homepage: http://github.com/jayferd/cacher
|
26
|
+
licenses: []
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project: cacher
|
45
|
+
rubygems_version: 1.8.10
|
46
|
+
signing_key:
|
47
|
+
specification_version: 3
|
48
|
+
summary: All your cache are belong to us
|
49
|
+
test_files: []
|