cachedis 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +46 -12
- data/lib/cachedis/version.rb +1 -1
- data/lib/cachedis.rb +24 -5
- data/spec/base_spec.rb +24 -2
- data/spec/interface_spec.rb +17 -0
- data/spec/spec_helper.rb +5 -4
- metadata +4 -2
data/README.md
CHANGED
@@ -1,24 +1,58 @@
|
|
1
1
|
# Cachedis
|
2
2
|
|
3
|
-
Cachedis caches your expensive queries to a Redis instance so the next time you fire it off, it'll load directly from cache instead of being run again.
|
3
|
+
Cachedis caches your expensive queries to a Redis instance so the next time you fire it off, it'll load directly from cache instead of being run again.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
# performs query the first time, performs cached calls to Redis within the next 60 * 60 seconds
|
8
|
-
@cachedis.cachedis 'name-of-expensive-query', :expire => 60 * 60 do
|
5
|
+
cachedis 'expensive:query', :expire => 60 * 60 do
|
9
6
|
Post.all.expensive_operation
|
10
7
|
end
|
11
8
|
|
9
|
+
## Documentation
|
10
|
+
|
11
|
+
You can specify two types of options via constants:
|
12
|
+
|
13
|
+
* `CACHEDIS_DEFAULT_OPTIONS`
|
14
|
+
- Passed directly to [redis-rb][rr]
|
15
|
+
- Options like host options, port options, etc.
|
16
|
+
* `CACHEDIS_DEFAULT_QUERY_OPTIONS`
|
17
|
+
- Default options for the `cachedis` queries
|
18
|
+
- For instance if you always want queries to expire in an hour:
|
19
|
+
- `CACHEDIS_DEFAULT_QUERY_OPTIONS = { :expire => 60 * 60 * 60}`
|
20
|
+
- Overridden by options passed to `cachedis` directly
|
21
|
+
|
22
|
+
`cachedis` takes two arguments in addition to a block which should return whatever you want `cachedis` to cache:
|
23
|
+
|
24
|
+
key, options = {}
|
25
|
+
|
26
|
+
The key is the name of the key under which the objects are saved as in Redis. Options are send directly to the Redis instance in along. For instance the option could be expiring the key at a certain time:
|
27
|
+
|
28
|
+
include CachedisInterface
|
29
|
+
|
30
|
+
# expire in an hour using Redis' EXPIRE command
|
31
|
+
cachedis 'users:all:with_avatars', :expire => 60 * 60 * 60 do
|
32
|
+
User.all.with_avatars
|
33
|
+
end
|
34
|
+
|
35
|
+
# expire at unix timestamp with Redis' EXPIREAT command
|
36
|
+
cachedis 'expensive:query', :expireat => Time.new(2012,2,2).to_i do
|
37
|
+
# insert expensive query here
|
38
|
+
end
|
39
|
+
|
12
40
|
## Installation and dependencies
|
13
41
|
|
14
|
-
Dependencies
|
42
|
+
Dependencies: [redis-rb][rr]
|
43
|
+
|
44
|
+
Install: `gem install cachedis`
|
15
45
|
|
16
|
-
|
46
|
+
[Redis](http://redis.io) should be running in the background, start it with `redis-server`.
|
17
47
|
|
18
|
-
## Wishlist
|
48
|
+
## Wishlist/To do/To consider
|
19
49
|
|
20
|
-
*
|
21
|
-
|
22
|
-
*
|
50
|
+
* ActiveRecord integration
|
51
|
+
- `Post.all.expensive_operation.cachedis`
|
52
|
+
* Make expirement time optional
|
53
|
+
* Best serializing?
|
23
54
|
* Sexify the API
|
24
|
-
- Make it easier to specialize expirement time (e.g. `:expire => 4.hours`)
|
55
|
+
- Make it easier to specialize expirement time (e.g. `:expire => 4.hours`), or just let this be for ActiveSupport users only?
|
56
|
+
* Rename `Cachedis#cachedis`?
|
57
|
+
|
58
|
+
[rr]: https://github.com/ezmobius/redis-rb
|
data/lib/cachedis/version.rb
CHANGED
data/lib/cachedis.rb
CHANGED
@@ -8,17 +8,36 @@ class Cachedis
|
|
8
8
|
redis(options)
|
9
9
|
end
|
10
10
|
|
11
|
-
def cachedis(
|
11
|
+
def cachedis(key, options = {}, &block)
|
12
12
|
result = yield
|
13
13
|
|
14
|
-
return redis.get
|
14
|
+
return redis.get key if redis.exists key
|
15
15
|
|
16
|
-
|
17
|
-
redis.
|
16
|
+
result = result.to_yaml
|
17
|
+
redis.set key, result
|
18
|
+
pass_options_to_redis(options)
|
19
|
+
|
20
|
+
result
|
18
21
|
end
|
19
22
|
|
20
|
-
private
|
21
23
|
def redis(options = {})
|
22
24
|
@redis_instance ||= Redis.new(options)
|
23
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def pass_options_to_redis(options)
|
29
|
+
options.each do |option, argument|
|
30
|
+
arguments = *[argument] if argument.is_a?(Array)
|
31
|
+
redis.send(option, arguments || argument)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module CachedisInterface
|
37
|
+
def self.cachedis(name, options = {}, &block)
|
38
|
+
cachedis = Cachedis.new((CACHEDIS_DEFAULT_OPTIONS if defined?(CACHEDIS_DEFAULT_OPTIONS))|| {})
|
39
|
+
|
40
|
+
query_options = ((CACHEDIS_DEFAULT_QUERY_OPTIONS if defined?(CACHEDIS_OPTIONS)) || {}).merge(options)
|
41
|
+
cachedis.cachedis(name, query_options, &block)
|
42
|
+
end
|
24
43
|
end
|
data/spec/base_spec.rb
CHANGED
@@ -9,8 +9,7 @@ describe Cachedis do
|
|
9
9
|
|
10
10
|
describe 'when setting something' do
|
11
11
|
it 'sets without errors' do
|
12
|
-
with_no_cache
|
13
|
-
@cachedis.redis_instance.should_receive(:set).exactly(1).times.and_return(['element', 'element 2'].to_yaml)
|
12
|
+
with_no_cache(['element', 'element 2'])
|
14
13
|
|
15
14
|
lambda {
|
16
15
|
@cachedis.cachedis 'expensive-query' do
|
@@ -31,4 +30,27 @@ describe Cachedis do
|
|
31
30
|
result.should == "query".to_yaml
|
32
31
|
end
|
33
32
|
end
|
33
|
+
|
34
|
+
describe 'when setting additonal redis parameters' do
|
35
|
+
context 'with one argument' do
|
36
|
+
it 'sets them in redis' do
|
37
|
+
with_no_cache
|
38
|
+
|
39
|
+
@cachedis.redis_instance.should_receive(:expire).exactly(1).times
|
40
|
+
|
41
|
+
@cachedis.cachedis 'name', :expire => 60 * 60 do
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with an array of arguments' do
|
47
|
+
it 'sets them in redis' do
|
48
|
+
with_no_cache
|
49
|
+
@cachedis.redis_instance.should_receive(:rename).exactly(1).times
|
50
|
+
|
51
|
+
@cachedis.cachedis 'name', :rename => ['key', 'otherkey'] do
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
34
56
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CachedisInterface do
|
4
|
+
include HelperMethods
|
5
|
+
|
6
|
+
describe 'when setting something' do
|
7
|
+
it 'sets without errors' do
|
8
|
+
@mock = mock(Cachedis)
|
9
|
+
Cachedis.should_receive(:new).exactly(1).times.and_return(@mock)
|
10
|
+
@mock.stub!(:cachedis).and_return(['element', 'element 2'])
|
11
|
+
|
12
|
+
CachedisInterface.cachedis 'expensive-query' do
|
13
|
+
['element', 'element 2']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,12 +4,13 @@ require 'cachedis'
|
|
4
4
|
require 'rspec'
|
5
5
|
|
6
6
|
module HelperMethods
|
7
|
-
def with_no_cache
|
8
|
-
@cachedis.
|
7
|
+
def with_no_cache(cache = nil)
|
8
|
+
@cachedis.redis.should_receive(:exists).exactly(1).times.and_return(false)
|
9
|
+
@cachedis.redis.should_receive(:set).exactly(1).times.and_return(cache)
|
9
10
|
end
|
10
11
|
|
11
12
|
def with_cache(cache)
|
12
|
-
@cachedis.
|
13
|
-
@cachedis.
|
13
|
+
@cachedis.redis.should_receive(:exists).exactly(1).times.and_return(true)
|
14
|
+
@cachedis.redis.should_receive(:get).exactly(1).times.and_return(cache.to_yaml)
|
14
15
|
end
|
15
16
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- "Simon H\xC3\xB8rup Eskildsen"
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/cachedis.rb
|
77
77
|
- lib/cachedis/version.rb
|
78
78
|
- spec/base_spec.rb
|
79
|
+
- spec/interface_spec.rb
|
79
80
|
- spec/spec_helper.rb
|
80
81
|
has_rdoc: true
|
81
82
|
homepage: ""
|
@@ -111,4 +112,5 @@ specification_version: 3
|
|
111
112
|
summary: Caches expensive database queries in Redis
|
112
113
|
test_files:
|
113
114
|
- spec/base_spec.rb
|
115
|
+
- spec/interface_spec.rb
|
114
116
|
- spec/spec_helper.rb
|