barking_iguana-cache_bucket 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -4
- data/barking_iguana-cache_bucket.gemspec +1 -0
- data/lib/barking_iguana/cache_bucket.rb +5 -9
- data/lib/barking_iguana/cache_bucket/cache_bucket.rb +11 -11
- data/lib/barking_iguana/cache_bucket/dsl.rb +30 -2
- data/lib/barking_iguana/cache_bucket/version.rb +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37fb5d68814bf9fd29d3dfbe8edb21ae5ec08399
|
4
|
+
data.tar.gz: 44ae25e4af0c0e80625eec93b6737f8ca9e0fa7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80a3dca076566a9c5d3327b5e693769b6e77bd0f52f955744796c7aec502f3230ca5f136257116adeee4299050f984f539c820f5d0c2349f4c238ea79e3804a4
|
7
|
+
data.tar.gz: 819e4aa1809b29eb301556e78f63d17f90e99b21a6afc232e169496c1db1183ca0f3e230aaa28d15b261bb416d4fc4188078422feccf0e438d612e7232dc601f
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# BarkingIguana::CacheBucket
|
2
2
|
|
3
|
-
|
3
|
+
Provides a naive but easy to set up cache with time based expiry.
|
4
4
|
|
5
|
-
|
5
|
+
Time based expiry in implemented as a maximum age that the cached objects _may_
|
6
|
+
reach. It's not a guarantee that the objects _will_ live that long.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
@@ -22,7 +23,86 @@ Or install it yourself as:
|
|
22
23
|
|
23
24
|
## Usage
|
24
25
|
|
25
|
-
|
26
|
+
Most likely you'll want to use the DSL in your class:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'barking_iguana/cache_bucket'
|
30
|
+
|
31
|
+
class Thing
|
32
|
+
include BarkingIguana::CacheBucket::DSL
|
33
|
+
|
34
|
+
def expensive_operation
|
35
|
+
cache_bucket.get 'expensive_operation' do
|
36
|
+
object_id
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
**BEWARE!** The cache will persist across instances of the class:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# Create two new instances of the class
|
46
|
+
t1 = Thing.new
|
47
|
+
t2 = Thing.new
|
48
|
+
|
49
|
+
# These have different object ids:
|
50
|
+
t1.object_id #=> 70248246472260
|
51
|
+
t2.object_id #=> 70248259056820
|
52
|
+
|
53
|
+
# But the same value is returned from both:
|
54
|
+
t1.expensive_operation #=> 70248246472260
|
55
|
+
t2.expensive_operation #=> 70248246472260
|
56
|
+
```
|
57
|
+
|
58
|
+
If you need `CacheBucket`s that are scoped to instances you should use a
|
59
|
+
`prefix`:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
class ScopedThing
|
63
|
+
include BarkingIguana::CacheBucket::DSL
|
64
|
+
|
65
|
+
def expensive_operation
|
66
|
+
cache_bucket.get 'expensive_operation', prefix: "instance_#{id}" do
|
67
|
+
object_id
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Create two new instances of the class
|
73
|
+
s1 = ScopedThing.new
|
74
|
+
s2 = ScopedThing.new
|
75
|
+
|
76
|
+
# These have different object ids:
|
77
|
+
s1.object_id #=> 70248246472260
|
78
|
+
s2.object_id #=> 70248259056820
|
79
|
+
|
80
|
+
# Now a different value is returned from both:
|
81
|
+
s1.expensive_operation #=> 70248246472260
|
82
|
+
s2.expensive_operation #=> 70248259056820
|
83
|
+
```
|
84
|
+
|
85
|
+
### Configuration
|
86
|
+
|
87
|
+
You may configure a few things about the behaviour of the `CacheBucket`s.
|
88
|
+
|
89
|
+
#### Logging
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
BarkingIguana::CacheBucket.logger = Logger.new($stdout)
|
93
|
+
```
|
94
|
+
|
95
|
+
It logs at `Logger::DEBUG`, so you won't see very much unless you crank the log
|
96
|
+
level of your logger _way_ up.
|
97
|
+
|
98
|
+
#### Cache Horizon
|
99
|
+
|
100
|
+
The default is 3600 seconds - one hour. You can set it to any number of seconds
|
101
|
+
though. Please note that I only support integer numbers of seconds.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
BarkingIguana::CacheBucket.maximum_age = 7200
|
105
|
+
```
|
26
106
|
|
27
107
|
## Development
|
28
108
|
|
@@ -32,5 +112,5 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
112
|
|
33
113
|
## Contributing
|
34
114
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
115
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/barking_iguana/cache_bucket.
|
36
116
|
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.require_paths = ["lib"]
|
28
28
|
|
29
29
|
spec.add_dependency "null_logger"
|
30
|
+
spec.add_dependency "barking_iguana-otk", "~> 0.1.0"
|
30
31
|
spec.add_development_dependency "bundler", "~> 1.11"
|
31
32
|
spec.add_development_dependency "rake", "~> 10.0"
|
32
33
|
spec.add_development_dependency "rspec", "~> 3.0"
|
@@ -1,18 +1,13 @@
|
|
1
|
+
require "barking_iguana/otk/defaults"
|
1
2
|
require "barking_iguana/cache_bucket/version"
|
2
3
|
require "barking_iguana/cache_bucket/cache_bucket"
|
3
4
|
require "barking_iguana/cache_bucket/dsl"
|
4
5
|
|
5
6
|
module BarkingIguana
|
6
7
|
module CacheBucket
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
self.logger = NullLogger.instance
|
11
|
-
|
12
|
-
class << self
|
13
|
-
attr_accessor :maximum_age
|
14
|
-
end
|
15
|
-
self.maximum_age = 3600
|
8
|
+
include Otk::Defaults
|
9
|
+
defaults logger: NullLogger.instance,
|
10
|
+
maximum_age: 3600
|
16
11
|
|
17
12
|
def self.get name, options = {}
|
18
13
|
buckets[name] ||= create_bucket name, options
|
@@ -29,5 +24,6 @@ module BarkingIguana
|
|
29
24
|
o[:maximum_age] ||= maximum_age
|
30
25
|
CacheBucket.new o
|
31
26
|
end
|
27
|
+
private_class_method :create_bucket
|
32
28
|
end
|
33
29
|
end
|
@@ -3,7 +3,9 @@ require 'null_logger'
|
|
3
3
|
module BarkingIguana
|
4
4
|
module CacheBucket
|
5
5
|
class CacheBucket
|
6
|
+
SHARED_PREFIX = '##shared##'.freeze
|
6
7
|
KEY_DIVIDER = '__'.freeze
|
8
|
+
MAXIMUM_AGE = 3600
|
7
9
|
|
8
10
|
attr_accessor :maximum_age
|
9
11
|
private :maximum_age=, :maximum_age
|
@@ -17,16 +19,16 @@ module BarkingIguana
|
|
17
19
|
attr_accessor :cache
|
18
20
|
private :cache=, :cache
|
19
21
|
|
20
|
-
def initialize maximum_age:
|
22
|
+
def initialize maximum_age: MAXIMUM_AGE, logger: nil
|
21
23
|
self.maximum_age = maximum_age.to_i
|
22
24
|
self.logger = logger || NullLogger.instance
|
23
25
|
self.cache = {}
|
24
26
|
end
|
25
27
|
|
26
|
-
def get key
|
27
|
-
logger.debug { "Getting #{key}" }
|
28
|
+
def get key, prefix: SHARED_PREFIX
|
28
29
|
evict_expired_keys
|
29
|
-
k = generation_key(key)
|
30
|
+
k = generation_key(key, prefix)
|
31
|
+
logger.debug { "Getting #{k.inspect} (key: #{key.inspect}, prefix: #{prefix.inspect})" }
|
30
32
|
if cache.key? k
|
31
33
|
logger.debug { "Key #{k.inspect} found in the cache" }
|
32
34
|
cache[k].tap do |v|
|
@@ -43,10 +45,10 @@ module BarkingIguana
|
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
|
-
def set key, value
|
48
|
+
def set key, value, prefix: SHARED_PREFIX
|
47
49
|
evict_expired_keys
|
48
|
-
k = generation_key(key)
|
49
|
-
logger.debug { "Setting
|
50
|
+
k = generation_key(key, prefix)
|
51
|
+
logger.debug { "Setting #{k.inspect} (key: #{key.inspect}, prefix: #{prefix.inspect}) to #{value.inspect}" }
|
50
52
|
cache[k] = value
|
51
53
|
end
|
52
54
|
|
@@ -68,10 +70,8 @@ module BarkingIguana
|
|
68
70
|
Time.now.to_i / maximum_age
|
69
71
|
end
|
70
72
|
|
71
|
-
def generation_key key
|
72
|
-
[ generation_id, key ].join(KEY_DIVIDER)
|
73
|
-
logger.debug { "Current generation key for #{key.inspect} is #{k.inspect}" }
|
74
|
-
end
|
73
|
+
def generation_key key, prefix
|
74
|
+
[ generation_id, prefix, key ].join(KEY_DIVIDER)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -1,5 +1,31 @@
|
|
1
1
|
module BarkingIguana
|
2
2
|
module CacheBucket
|
3
|
+
# Include this DSL in classes where you'd like to easily access a
|
4
|
+
# `CacheBucket` instance named after the class it's being included into.
|
5
|
+
#
|
6
|
+
# In each class and instance of that class you'll get access to a
|
7
|
+
# `cache_bucket` method to provide access to a `CacheBucket`.
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# class Example
|
11
|
+
# def self.class_method
|
12
|
+
# cache_bucket.get 'foo' do
|
13
|
+
# 'bar_set_in_class_method'
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# def instance_method
|
18
|
+
# puts cache_bucket.get 'foo'
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Given the above class definition, here's some example output:
|
23
|
+
#
|
24
|
+
# Example.class_method
|
25
|
+
# Example.new.instance_method #=> 'bar_set_in_class_method'
|
26
|
+
#
|
27
|
+
# It's hard to imagine a place where you'll actually want to use the
|
28
|
+
# instance variable of this, and it may be removed in future releases.
|
3
29
|
module DSL
|
4
30
|
def self.included into
|
5
31
|
into.extend ClassMethods
|
@@ -7,13 +33,15 @@ module BarkingIguana
|
|
7
33
|
end
|
8
34
|
|
9
35
|
module InstanceMethods
|
10
|
-
|
36
|
+
# Access the Cache Bucket for thisinstances class.
|
37
|
+
def cache_bucket options = {}
|
11
38
|
BarkingIguana::CacheBucket.get self.class.name, options
|
12
39
|
end
|
13
40
|
end
|
14
41
|
|
15
42
|
module ClassMethods
|
16
|
-
|
43
|
+
# Access the Cache Bucket for this class.
|
44
|
+
def cache_bucket options = {}
|
17
45
|
BarkingIguana::CacheBucket.get name, options
|
18
46
|
end
|
19
47
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: barking_iguana-cache_bucket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Craig R Webster
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: barking_iguana-otk
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|