reserve 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +22 -0
- data/.travis.yml +5 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +27 -0
- data/lib/reserve.rb +9 -0
- data/lib/reserve/store.rb +68 -0
- data/lib/reserve/version.rb +3 -0
- data/reserve.gemspec +28 -0
- data/spec/reserve_spec.rb +65 -0
- data/spec/spec_helper.rb +14 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1f141fe333f536dbae5929d71ebeaf1494ec6ff1
|
4
|
+
data.tar.gz: 425e55a52012154a1da31d770359c527002a72ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7245340a40f8bd78c3de35d976eceddbae0c3841b69c191f4c2f805b238374292246684c75e478bdc1f41b126739940a732a8cc559d3efec9e5b031b360d5ecf
|
7
|
+
data.tar.gz: 8dcb7ab8dae8c269d0d69367982a156577c83cc6378352c38c3a3f042394dd99e23d5ceb91e446fd38d734bef129e2c2128feafcd1f8a3cc0ec8e38ec37cc5f9
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Nick Charlton
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# reserve - caching library based around Redis EXPIRE
|
2
|
+
|
3
|
+
[](https://travis-ci.org/nickcharlton/reserve-ruby)
|
4
|
+
[](https://coveralls.io/r/nickcharlton/reserve-ruby)
|
5
|
+
[](http://inch-ci.org/github/nickcharlton/reserve-ruby)
|
6
|
+
|
7
|
+
This gem provides simple object caching support using Redis.
|
8
|
+
|
9
|
+
It works around the concept of "faulting"; you request an object from the
|
10
|
+
cache and if it already exists it will return the cached object. If not, it'll
|
11
|
+
execute the associated block to generate it instead.
|
12
|
+
|
13
|
+
Using Redis' `EXPIRE` functionality, the cached object can be set to
|
14
|
+
automatically disappear after a set period of time.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Reserve isn't (yet) on [RubyGems][], so add the repo to your [Gemfile][]:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'reserve', :git => 'https://github.com/nickcharlton/reserve-ruby.git'
|
22
|
+
```
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
reserve = Reserve.new(Redis.new)
|
28
|
+
|
29
|
+
# store an item with a given key
|
30
|
+
item = reserve.store :item do
|
31
|
+
{ value: "this is item" }
|
32
|
+
end
|
33
|
+
|
34
|
+
item # => { value: "this is item" }
|
35
|
+
```
|
36
|
+
|
37
|
+
Both `Reserve.new` and `store` accept a hash of options, but they're a little
|
38
|
+
bit different for each:
|
39
|
+
|
40
|
+
For `Reserve.new`:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
default_timeout: 3600 # the default timeout to use with store.
|
44
|
+
key_prefix: 'reserve' # the prefix to use in Redis.
|
45
|
+
```
|
46
|
+
|
47
|
+
For `store`:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
timeout: 3600 # the timeout to use when storing this item.
|
51
|
+
skip_cache: true # skip the cache in this invokation (great for testing).
|
52
|
+
```
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
1. Fork it
|
57
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
58
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
59
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
5. Create a new Pull Request
|
61
|
+
|
62
|
+
## Author
|
63
|
+
|
64
|
+
Copyright (c) 2014 Nick Charlton <nick@nickcharlton.net>
|
65
|
+
|
66
|
+
[RubyGems]: http://rubygems.org
|
67
|
+
[Gemfile]: http://bundler.io
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
##
|
2
|
+
# Initialise Bundler, catch errors.
|
3
|
+
##
|
4
|
+
require 'bundler'
|
5
|
+
require 'bundler/gem_tasks'
|
6
|
+
|
7
|
+
begin
|
8
|
+
Bundler.setup(:default, :development)
|
9
|
+
rescue Bundler::BundlerError => e
|
10
|
+
$stderr.puts e.message
|
11
|
+
$stderr.puts "Run `bundle install` to install missing gems."
|
12
|
+
exit e.status_code
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Configure the test suite.
|
17
|
+
##
|
18
|
+
require 'rake/testtask'
|
19
|
+
|
20
|
+
Rake::TestTask.new :spec do |t|
|
21
|
+
t.test_files = Dir['spec/*_spec.rb']
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# By default, just run the tests.
|
26
|
+
##
|
27
|
+
task :default => :spec
|
data/lib/reserve.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Reserve
|
4
|
+
class Store
|
5
|
+
attr_accessor :redis
|
6
|
+
attr_accessor :default_timeout
|
7
|
+
attr_accessor :key_prefix
|
8
|
+
|
9
|
+
# Returns a new instance of Store
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# item = Reserve::Store.new(Redis.new)
|
13
|
+
#
|
14
|
+
# @param redis [Object] Redis-like instance for storing items.
|
15
|
+
# @param [Hash] opts the options to configure a new instance.
|
16
|
+
# @option opts [Integer] :default_timeout The default key expiry.
|
17
|
+
# @option opts [String] :key_prefix The word to prefix redis keys with.
|
18
|
+
def initialize redis, opts={}
|
19
|
+
@redis = redis
|
20
|
+
|
21
|
+
@default_timeout = opts[:default_timeout] || 10800
|
22
|
+
@key_prefix = opts[:key_prefix] || 'reserve'
|
23
|
+
end
|
24
|
+
|
25
|
+
# Cache a block with a given key.
|
26
|
+
#
|
27
|
+
# @example Simple
|
28
|
+
# item = reserve.store :item do
|
29
|
+
# { value: 'this is item' }
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# @param key [String] key to store the block under.
|
33
|
+
# @param [Hash] opts the options to cache the block
|
34
|
+
# @option opts [String] :timeout value to set the key expiry to be.
|
35
|
+
# @option opts [String] :skip_cache skip the cache and execute the block
|
36
|
+
# regardess of whether or not it's stored.
|
37
|
+
def store key, opts={}, &block
|
38
|
+
real_key = "#{@key_prefix}_#{key.to_s}"
|
39
|
+
timeout = opts[:timeout] || @default_timeout
|
40
|
+
|
41
|
+
if opts[:skip_cache]
|
42
|
+
return block.call
|
43
|
+
end
|
44
|
+
|
45
|
+
item = @redis.get real_key
|
46
|
+
if item
|
47
|
+
item = JSON.parse item, {symbolize_names: true}
|
48
|
+
else
|
49
|
+
item = block.call
|
50
|
+
|
51
|
+
@redis.pipelined do
|
52
|
+
@redis.set real_key, item.to_json
|
53
|
+
@redis.expire real_key, timeout
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
item
|
58
|
+
end
|
59
|
+
|
60
|
+
# Clears all of the stored items.
|
61
|
+
def clear
|
62
|
+
keys = @redis.keys "#{@key_prefix}*"
|
63
|
+
unless keys.empty?
|
64
|
+
@redis.del keys
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/reserve.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'reserve/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'reserve'
|
8
|
+
spec.version = Reserve::VERSION
|
9
|
+
spec.authors = ['Nick Charlton']
|
10
|
+
spec.email = ['nick@nickcharlton.net']
|
11
|
+
spec.summary = %q{An object caching library for Redis.}
|
12
|
+
spec.description = %q{An object caching library for Redis.}
|
13
|
+
spec.homepage = 'https://github.com/nickcharlton/reserve-ruby'
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'redis', '~> 3.1.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'mock_redis'
|
26
|
+
spec.add_development_dependency 'pry'
|
27
|
+
spec.add_development_dependency 'yard'
|
28
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# test helpers
|
2
|
+
require File.expand_path 'spec_helper.rb', __dir__
|
3
|
+
|
4
|
+
describe 'Reserve Main Methods' do
|
5
|
+
before do
|
6
|
+
# use MockRedis if just testing, real redis if in CI or if USE_REDIS is set.
|
7
|
+
if ENV['CI'] || ENV['USE_REDIS']
|
8
|
+
@redis = Redis.new
|
9
|
+
else
|
10
|
+
@redis = MockRedis.new
|
11
|
+
end
|
12
|
+
|
13
|
+
@reserve = Reserve.new(@redis)
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
@reserve.clear
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'stores a simple object using a key' do
|
21
|
+
item = @reserve.store :item do
|
22
|
+
{ value: "this is item" }
|
23
|
+
end
|
24
|
+
|
25
|
+
item.wont_be_nil
|
26
|
+
item.must_be_kind_of Hash
|
27
|
+
item.must_equal({value: "this is item"})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'sets the (default) timeout correctly on an object' do
|
31
|
+
item = @reserve.store :item do
|
32
|
+
{ value: "this is item" }
|
33
|
+
end
|
34
|
+
|
35
|
+
item.wont_be_nil
|
36
|
+
item_ttl = @redis.ttl("reserve_#{:item.to_s}")
|
37
|
+
item_ttl.must_equal 10800
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'works with a custom timeout' do
|
41
|
+
item = @reserve.store :item, timeout: 3600 do
|
42
|
+
{ value: "this is item" }
|
43
|
+
end
|
44
|
+
|
45
|
+
item.wont_be_nil
|
46
|
+
item_ttl = @redis.ttl("reserve_#{:item.to_s}")
|
47
|
+
item_ttl.must_equal 3600
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'can skip the cache with an option' do
|
51
|
+
standard_item = @reserve.store :item do
|
52
|
+
{ value: "this is item" }
|
53
|
+
end
|
54
|
+
|
55
|
+
standard_item.wont_be_nil
|
56
|
+
|
57
|
+
clean_item = @reserve.store :item, skip_cache: true do
|
58
|
+
{ value: "this is a different item" }
|
59
|
+
end
|
60
|
+
|
61
|
+
clean_item.wont_be_nil
|
62
|
+
|
63
|
+
standard_item.wont_equal clean_item
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# test coverage
|
2
|
+
require 'coveralls'
|
3
|
+
|
4
|
+
# enable coveralls
|
5
|
+
Coveralls.wear!
|
6
|
+
|
7
|
+
# test framework
|
8
|
+
require 'minitest/autorun'
|
9
|
+
require 'minitest/pride'
|
10
|
+
require 'redis'
|
11
|
+
require 'mock_redis'
|
12
|
+
|
13
|
+
# pull in the library
|
14
|
+
require File.expand_path '../lib/reserve.rb', __dir__
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reserve
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Charlton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mock_redis
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: An object caching library for Redis.
|
98
|
+
email:
|
99
|
+
- nick@nickcharlton.net
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".coveralls.yml"
|
105
|
+
- ".gitignore"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- lib/reserve.rb
|
112
|
+
- lib/reserve/store.rb
|
113
|
+
- lib/reserve/version.rb
|
114
|
+
- reserve.gemspec
|
115
|
+
- spec/reserve_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
homepage: https://github.com/nickcharlton/reserve-ruby
|
118
|
+
licenses:
|
119
|
+
- MIT
|
120
|
+
metadata: {}
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 2.2.2
|
138
|
+
signing_key:
|
139
|
+
specification_version: 4
|
140
|
+
summary: An object caching library for Redis.
|
141
|
+
test_files:
|
142
|
+
- spec/reserve_spec.rb
|
143
|
+
- spec/spec_helper.rb
|
144
|
+
has_rdoc:
|