coffee_table 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +19 -22
- data/README.textile +1 -0
- data/changelog.txt +4 -1
- data/lib/coffee_table.rb +18 -24
- data/lib/coffee_table/version.rb +1 -1
- data/spec/lib/coffee_table_spec.rb +30 -30
- data/spec/spec_helper.rb +7 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d87f1f9b02a63db0921133ad996a2c633b6b73a8
|
4
|
+
data.tar.gz: dfb007210368795bbd1351fa27e03788e6b1a950
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0eeb7161d82bea4df39f2a9778eaffffa34490e3119ee72277b30f19ec0d1219b1457f65ba521cb230bc8ff25a4e32a045e57d2deb8b4cc6af511deb404e611
|
7
|
+
data.tar.gz: c909abec5091d2da8717b10da06bab7da55385661e03ef876a4db5ac0da2dccaeb28bbfa369cd43df4bf04a91234a021d2a407231e05566ab3709193dac71a3b
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,17 +1,7 @@
|
|
1
|
-
GIT
|
2
|
-
remote: git@github.com:stewartmckee/sourcify.git
|
3
|
-
revision: cdef8e0b3b7017312407000985a279d6627c77e5
|
4
|
-
specs:
|
5
|
-
sourcify (0.6.0.rc3)
|
6
|
-
file-tail (~> 1.0.10)
|
7
|
-
ruby2ruby (~> 1.3.1)
|
8
|
-
ruby_parser (~> 2.3.1)
|
9
|
-
sexp_processor (~> 3.2.0)
|
10
|
-
|
11
1
|
PATH
|
12
2
|
remote: .
|
13
3
|
specs:
|
14
|
-
coffee_table (0.2.
|
4
|
+
coffee_table (0.2.3)
|
15
5
|
activesupport
|
16
6
|
gzip
|
17
7
|
redis
|
@@ -33,13 +23,15 @@ GEM
|
|
33
23
|
simplecov (>= 0.7)
|
34
24
|
thor
|
35
25
|
diff-lcs (1.2.4)
|
36
|
-
file-tail (1.
|
37
|
-
tins (~> 0
|
26
|
+
file-tail (1.1.1)
|
27
|
+
tins (~> 1.0)
|
38
28
|
gzip (1.0)
|
39
29
|
i18n (0.6.4)
|
40
30
|
mime-types (1.23)
|
41
|
-
mock_redis (0.
|
31
|
+
mock_redis (0.17.0)
|
42
32
|
multi_json (1.7.8)
|
33
|
+
proc_extensions (0.2)
|
34
|
+
sourcify (~> 0.5)
|
43
35
|
redis (3.2.2)
|
44
36
|
rest-client (1.6.7)
|
45
37
|
mime-types (>= 1.16)
|
@@ -51,21 +43,26 @@ GEM
|
|
51
43
|
rspec-expectations (2.14.1)
|
52
44
|
diff-lcs (>= 1.1.3, < 2.0)
|
53
45
|
rspec-mocks (2.14.3)
|
54
|
-
ruby2ruby (
|
55
|
-
ruby_parser (~>
|
56
|
-
sexp_processor (~>
|
57
|
-
ruby_parser (
|
58
|
-
sexp_processor (~>
|
46
|
+
ruby2ruby (2.3.0)
|
47
|
+
ruby_parser (~> 3.1)
|
48
|
+
sexp_processor (~> 4.0)
|
49
|
+
ruby_parser (3.8.2)
|
50
|
+
sexp_processor (~> 4.1)
|
59
51
|
rufus-scheduler (2.0.23)
|
60
52
|
tzinfo (>= 0.3.23)
|
61
|
-
sexp_processor (
|
53
|
+
sexp_processor (4.7.0)
|
62
54
|
simplecov (0.7.1)
|
63
55
|
multi_json (~> 1.0)
|
64
56
|
simplecov-html (~> 0.7.1)
|
65
57
|
simplecov-html (0.7.1)
|
58
|
+
sourcify (0.5.0)
|
59
|
+
file-tail (>= 1.0.5)
|
60
|
+
ruby2ruby (>= 1.2.5)
|
61
|
+
ruby_parser (>= 2.0.5)
|
62
|
+
sexp_processor (>= 3.0.5)
|
66
63
|
spork (0.9.2)
|
67
64
|
thor (0.18.1)
|
68
|
-
tins (
|
65
|
+
tins (1.12.0)
|
69
66
|
tzinfo (1.0.1)
|
70
67
|
|
71
68
|
PLATFORMS
|
@@ -78,9 +75,9 @@ DEPENDENCIES
|
|
78
75
|
coveralls
|
79
76
|
gzip
|
80
77
|
mock_redis
|
78
|
+
proc_extensions
|
81
79
|
rspec
|
82
80
|
rufus-scheduler
|
83
|
-
sourcify!
|
84
81
|
spork
|
85
82
|
|
86
83
|
BUNDLED WITH
|
data/README.textile
CHANGED
@@ -33,6 +33,7 @@ Creates a new cache object. You can pass options into this method to modify the
|
|
33
33
|
|
34
34
|
* :enable_cache This defaults to true, but can be set to false to disable the cache
|
35
35
|
* :redis_namespace defaults to ":coffee_table" and is set to seperate out the keys from other redis users or other caches
|
36
|
+
* :redis defaults to nil and can be used to pass in a redis connection, this overrides all other redis params
|
36
37
|
* :redis_server defaults to "127.0.0.1"
|
37
38
|
* :redis_port defaults to 6789
|
38
39
|
* :ignore_code_changes defaults to false. By default a md5 hash of the code in the block is included in the key, if you change the code, the key automatically invalidates. This is to protect against code changes that won't be picked up due to the cache returning.
|
data/changelog.txt
CHANGED
data/lib/coffee_table.rb
CHANGED
@@ -9,13 +9,13 @@ require 'rufus/scheduler'
|
|
9
9
|
require 'active_support/inflector'
|
10
10
|
require 'digest/md5'
|
11
11
|
require 'gzip'
|
12
|
+
require "proc_extensions"
|
12
13
|
|
13
14
|
module CoffeeTable
|
14
15
|
class Cache
|
15
16
|
|
16
17
|
include CoffeeTable::Utility
|
17
18
|
|
18
|
-
|
19
19
|
# initialize for coffee_table. takes options to setup behaviour of cache
|
20
20
|
def initialize(options={})
|
21
21
|
@options = options
|
@@ -24,24 +24,31 @@ module CoffeeTable
|
|
24
24
|
default_redis_namespace_to :coffee_table
|
25
25
|
default_redis_server_to "127.0.0.1"
|
26
26
|
default_redis_port_to 6379
|
27
|
+
default_redis_to nil
|
27
28
|
default_ignore_code_changes_to false
|
28
29
|
default_compress_content_to true
|
29
30
|
default_compress_min_size_to 10240
|
30
|
-
default_max_threads_to
|
31
|
+
default_max_threads_to 5
|
31
32
|
|
33
|
+
if !@options[:redis].nil?
|
34
|
+
@redis = @options[:redis]
|
35
|
+
elsif @options.has_key?(:redis_url)
|
36
|
+
@redis = Redis.new({:url => @options[:redis_url]})
|
37
|
+
else
|
38
|
+
@redis = Redis.new({:server => @options[:redis_server], :port => @options[:redis_port]})
|
39
|
+
end
|
32
40
|
rufus_version = Gem::Version.new(Rufus::Scheduler::VERSION)
|
33
41
|
if rufus_version >= Gem::Version.new('3.0.0')
|
34
|
-
@scheduler = Rufus::Scheduler.new(:max_work_threads
|
42
|
+
@scheduler = Rufus::Scheduler.new(:max_work_threads )
|
35
43
|
else
|
36
44
|
@scheduler = Rufus::Scheduler.start_new
|
37
45
|
end
|
38
46
|
end
|
39
47
|
|
48
|
+
|
40
49
|
def fetch(initial_key, *related_objects, &block)
|
41
50
|
raise CoffeeTable::BlockMissingError, "No block given to generate cache from" unless block_given?
|
42
51
|
|
43
|
-
@redis = get_redis
|
44
|
-
|
45
52
|
# extract the options hash if it is present
|
46
53
|
options = {}
|
47
54
|
if related_objects[-1].instance_of? Hash
|
@@ -52,11 +59,12 @@ module CoffeeTable
|
|
52
59
|
# check objects are valid
|
53
60
|
related_objects.flatten.map{|o| raise CoffeeTable::InvalidObjectError, "Objects passed in must have an id method or be a class" unless object_valid?(o)}
|
54
61
|
|
55
|
-
|
62
|
+
if @options[:ignore_code_changes]
|
56
63
|
block_key = ""
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
else
|
65
|
+
block_source = RubyVM::InstructionSequence.disasm(block.to_proc).to_s.gsub(/\(\s*\d+\)/, "").gsub(/^== disasm.*?$/, "")
|
66
|
+
block_key = Digest::MD5.hexdigest(block_source)
|
67
|
+
end
|
60
68
|
|
61
69
|
flags = {}
|
62
70
|
|
@@ -101,18 +109,14 @@ module CoffeeTable
|
|
101
109
|
else
|
102
110
|
result = yield
|
103
111
|
end
|
104
|
-
|
105
|
-
@redis.close
|
106
112
|
result
|
107
113
|
end
|
108
114
|
|
109
115
|
def expire_key(key_value)
|
110
|
-
@redis = get_redis
|
111
116
|
keys.map{|k| CoffeeTable::Key.parse(k)}.select{|key| key.has_element?(key_value) || key.to_s == key_value }.each do |key|
|
112
117
|
@redis.del(key.to_s)
|
113
118
|
@redis.srem "cache_keys", key.to_s
|
114
119
|
end
|
115
|
-
@redis.close
|
116
120
|
end
|
117
121
|
|
118
122
|
def expire_all
|
@@ -120,10 +124,7 @@ module CoffeeTable
|
|
120
124
|
end
|
121
125
|
|
122
126
|
def keys
|
123
|
-
@redis
|
124
|
-
members = @redis.smembers("cache_keys")
|
125
|
-
@redis.close
|
126
|
-
memberss
|
127
|
+
@redis.smembers("cache_keys")
|
127
128
|
end
|
128
129
|
|
129
130
|
def expire_for(*objects)
|
@@ -183,12 +184,5 @@ module CoffeeTable
|
|
183
184
|
def object_valid?(o)
|
184
185
|
o.respond_to?(:id) || o.class == Class
|
185
186
|
end
|
186
|
-
def get_redis
|
187
|
-
if @options.has_key?(:redis_url)
|
188
|
-
return Redis.new({:url => @options[:redis_url]})
|
189
|
-
else
|
190
|
-
return Redis.new({:server => @options[:redis_server], :port => @options[:redis_port]})
|
191
|
-
end
|
192
|
-
end
|
193
187
|
end
|
194
188
|
end
|
data/lib/coffee_table/version.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
2
|
+
require "base64"
|
3
3
|
describe CoffeeTable::Cache do
|
4
|
-
|
4
|
+
|
5
5
|
before(:each) do
|
6
6
|
@coffee_table = CoffeeTable::Cache.new
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
specify { CoffeeTable::Cache.should respond_to :new}
|
10
10
|
specify { @coffee_table.should respond_to :fetch}
|
11
11
|
specify { @coffee_table.should respond_to :expire_key}
|
12
12
|
specify { @coffee_table.should respond_to :expire_all}
|
13
13
|
specify { @coffee_table.should respond_to :keys}
|
14
14
|
specify { @coffee_table.should respond_to :expire_for}
|
15
|
-
|
15
|
+
|
16
16
|
describe "config" do
|
17
17
|
it "should take a hash for config" do
|
18
18
|
CoffeeTable::Cache.new({:test => "asdf"})
|
@@ -21,7 +21,7 @@ describe CoffeeTable::Cache do
|
|
21
21
|
lambda{CoffeeTable::Cache.new}.should_not raise_exception
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
describe "fetch" do
|
26
26
|
it "should raise an exception when block not given" do
|
27
27
|
lambda{@coffee_table.fetch("asdf")}.should raise_exception CoffeeTable::BlockMissingError
|
@@ -30,8 +30,8 @@ describe CoffeeTable::Cache do
|
|
30
30
|
result = @coffee_table.fetch("asdf") do
|
31
31
|
"this is a value"
|
32
32
|
end
|
33
|
-
|
34
|
-
result.should == "this is a value"
|
33
|
+
|
34
|
+
result.should == "this is a value"
|
35
35
|
end
|
36
36
|
it "should return cached value when cache available" do
|
37
37
|
value = "this is a value"
|
@@ -42,9 +42,9 @@ describe CoffeeTable::Cache do
|
|
42
42
|
result = @coffee_table.fetch("asdf") do
|
43
43
|
value
|
44
44
|
end
|
45
|
-
|
46
|
-
result.should == "this is a value"
|
47
|
-
|
45
|
+
|
46
|
+
result.should == "this is a value"
|
47
|
+
|
48
48
|
end
|
49
49
|
|
50
50
|
context "compressing" do
|
@@ -61,7 +61,7 @@ describe CoffeeTable::Cache do
|
|
61
61
|
"this string should be long"
|
62
62
|
end
|
63
63
|
result.should eql "this string should be long"
|
64
|
-
@redis.get("test_key|
|
64
|
+
@redis.get("test_key|1c083b7ed4b406f263ef329a608a80b9|compressed=true").should eq Marshal.dump(zipped_content)
|
65
65
|
end
|
66
66
|
it "does not compress on non strings" do
|
67
67
|
@coffee_table = CoffeeTable::Cache.new(:compress_min_size => 20)
|
@@ -69,7 +69,7 @@ describe CoffeeTable::Cache do
|
|
69
69
|
{:test => "this value is a decent length to trigger compress"}
|
70
70
|
end
|
71
71
|
result.should eql ({:test => "this value is a decent length to trigger compress"})
|
72
|
-
@redis.get("test_key|
|
72
|
+
Base64.encode64(@redis.get("test_key|6edc6a13bfb5a9f926072f34d1006557|")).should eql "BAh7BjoJdGVzdEkiNnRoaXMgdmFsdWUgaXMgYSBkZWNlbnQgbGVuZ3RoIHRv\nIHRyaWdnZXIgY29tcHJlc3MGOgZFVA==\n"
|
73
73
|
end
|
74
74
|
|
75
75
|
it "does not compress when turned off" do
|
@@ -78,7 +78,7 @@ describe CoffeeTable::Cache do
|
|
78
78
|
"this string should be long"
|
79
79
|
end
|
80
80
|
result.should eql "this string should be long"
|
81
|
-
@redis.get("test_key|
|
81
|
+
@redis.get("test_key|1c083b7ed4b406f263ef329a608a80b9|").should eql Marshal.dump("this string should be long")
|
82
82
|
end
|
83
83
|
it "does not compress on strings below limit" do
|
84
84
|
@coffee_table = CoffeeTable::Cache.new(:compress_min_size => 20)
|
@@ -86,7 +86,7 @@ describe CoffeeTable::Cache do
|
|
86
86
|
"short"
|
87
87
|
end
|
88
88
|
result.should eql "short"
|
89
|
-
@redis.get("test_key|
|
89
|
+
@redis.get("test_key|f0b9a08ff52e14e59daa03aae70a5cab|").should eql Marshal.dump("short")
|
90
90
|
end
|
91
91
|
it "decompresses compressed value" do
|
92
92
|
@coffee_table = CoffeeTable::Cache.new(:compress_min_size => 20)
|
@@ -134,7 +134,7 @@ describe CoffeeTable::Cache do
|
|
134
134
|
end
|
135
135
|
@coffee_table.keys.should == ["test_key|#{md5}|sample_classes|"]
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
it "should use class name for keys" do
|
139
139
|
md5 = md5_block do
|
140
140
|
"this is a changed value"
|
@@ -167,9 +167,9 @@ describe CoffeeTable::Cache do
|
|
167
167
|
result = @coffee_table.fetch(:test_key, test_object) do
|
168
168
|
"this is a changed value"
|
169
169
|
end
|
170
|
-
|
170
|
+
|
171
171
|
@coffee_table.keys.should include "test_key|#{md5}|sample_class[9938]|"
|
172
|
-
|
172
|
+
|
173
173
|
end
|
174
174
|
it "should raise an exception if a related object does not respond_to id" do
|
175
175
|
test_object = SampleClassWithoutId.new
|
@@ -179,7 +179,7 @@ describe CoffeeTable::Cache do
|
|
179
179
|
"this is a changed value"
|
180
180
|
end
|
181
181
|
}.should raise_exception CoffeeTable::InvalidObjectError, "Objects passed in must have an id method or be a class"
|
182
|
-
|
182
|
+
|
183
183
|
end
|
184
184
|
|
185
185
|
it "should create a universal key if the objects passed in are an uninitialised class" do
|
@@ -190,8 +190,8 @@ describe CoffeeTable::Cache do
|
|
190
190
|
result = @coffee_table.fetch(:test_key, SampleClass) do
|
191
191
|
"this is a changed value"
|
192
192
|
end
|
193
|
-
|
194
|
-
@coffee_table.keys.should include "test_key|#{md5}|sample_classes|"
|
193
|
+
|
194
|
+
@coffee_table.keys.should include "test_key|#{md5}|sample_classes|"
|
195
195
|
end
|
196
196
|
|
197
197
|
end
|
@@ -212,8 +212,8 @@ describe CoffeeTable::Cache do
|
|
212
212
|
value = 'this is a changed value'
|
213
213
|
result = @coffee_table.fetch("asdf") do
|
214
214
|
value
|
215
|
-
end
|
216
|
-
result.should == "this is a value"
|
215
|
+
end
|
216
|
+
result.should == "this is a value"
|
217
217
|
|
218
218
|
end
|
219
219
|
it "should execute block and return value when cache has expired" do
|
@@ -223,8 +223,8 @@ describe CoffeeTable::Cache do
|
|
223
223
|
sleep 2
|
224
224
|
result = @coffee_table.fetch("asdf") do
|
225
225
|
"this is a changed value"
|
226
|
-
end
|
227
|
-
result.should == "this is a changed value"
|
226
|
+
end
|
227
|
+
result.should == "this is a changed value"
|
228
228
|
end
|
229
229
|
end
|
230
230
|
|
@@ -251,7 +251,7 @@ describe CoffeeTable::Cache do
|
|
251
251
|
end
|
252
252
|
end
|
253
253
|
end
|
254
|
-
|
254
|
+
|
255
255
|
describe "expire_key" do
|
256
256
|
|
257
257
|
before(:each) do
|
@@ -377,7 +377,7 @@ describe CoffeeTable::Cache do
|
|
377
377
|
end
|
378
378
|
end
|
379
379
|
end
|
380
|
-
|
380
|
+
|
381
381
|
describe "expire_all" do
|
382
382
|
before(:each) do
|
383
383
|
|
@@ -409,7 +409,7 @@ describe CoffeeTable::Cache do
|
|
409
409
|
|
410
410
|
end
|
411
411
|
end
|
412
|
-
|
412
|
+
|
413
413
|
describe "keys" do
|
414
414
|
before(:each) do
|
415
415
|
@object1 = [SampleClass.new(1), SampleClass.new(2), SampleClass.new(3)]
|
@@ -464,7 +464,7 @@ describe CoffeeTable::Cache do
|
|
464
464
|
end
|
465
465
|
|
466
466
|
end
|
467
|
-
|
467
|
+
|
468
468
|
describe "expire_for" do
|
469
469
|
before(:each) do
|
470
470
|
object1 = [SampleClass.new(1), SampleClass.new(2), SampleClass.new(3)]
|
@@ -526,5 +526,5 @@ describe CoffeeTable::Cache do
|
|
526
526
|
@coffee_table.keys.count.should == 1
|
527
527
|
end
|
528
528
|
end
|
529
|
-
|
530
|
-
end
|
529
|
+
|
530
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -21,26 +21,27 @@ end
|
|
21
21
|
Spork.each_run do
|
22
22
|
RSpec.configure do |config|
|
23
23
|
config.before(:each) {
|
24
|
-
|
25
|
-
|
24
|
+
|
25
|
+
|
26
26
|
redis = double(:redis)
|
27
27
|
Redis.stub(:new).and_return(MockRedis.new)
|
28
28
|
CoffeeTable::Cache.new.expire_all
|
29
|
-
|
29
|
+
|
30
30
|
}
|
31
31
|
|
32
32
|
config.after(:each) {
|
33
33
|
}
|
34
|
-
end
|
34
|
+
end
|
35
35
|
end
|
36
36
|
|
37
37
|
def load_sample(filename)
|
38
|
-
File.open(File.dirname(__FILE__) + "/samples/" + filename).map { |line| line}.join("\n")
|
38
|
+
File.open(File.dirname(__FILE__) + "/samples/" + filename).map { |line| line}.join("\n")
|
39
39
|
end
|
40
40
|
def load_binary_sample(filename)
|
41
41
|
File.open(File.dirname(__FILE__) + "/samples/" + filename, 'rb')
|
42
42
|
end
|
43
43
|
|
44
44
|
def md5_block(&block)
|
45
|
-
|
45
|
+
block_source = RubyVM::InstructionSequence.disasm(block.to_proc).to_s.gsub(/\(\s*\d+\)/, "").gsub(/^== disasm.*?$/, "")
|
46
|
+
Digest::MD5.hexdigest(block_source)
|
46
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coffee_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stewart McKee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|