cache_for 1.1.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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OGM5ZTkxOTE1MDExMjIzMDU5Y2MwZWZjYzhhMDYzYmExN2U5ZTNiZQ==
5
+ data.tar.gz: !binary |-
6
+ YmExZjMyOTEwY2I2OWI0ZDFjYjMzMDhkMGFhYTdiMTg1NGQ2YTIxMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YzkzODRlY2IwNzIwMjZkNGM1OWI4MmExZWNhNzM2MTFhNGE2N2ZhOWE5YzM1
10
+ MmNlZmFhOWQxZDQ1NTJlZDgyYjFhMTQ5ODJlNjc3M2MyODU0MTQ3ZWMzOGIw
11
+ NGQwMjA3YjY5ZmJhNTYxNDYxOTUxNzk2MzljYWFhYzJjYWQ1ODI=
12
+ data.tar.gz: !binary |-
13
+ NTgyMDI2MmZiNDM3NjhjMzBiMGU5OGZhM2I4YzVmMmViNDA5ZGM1NmNlZjMy
14
+ OTI3MmQ5NzM1Y2JhNTVhMzE1ZDJjOWQzMGY1NmMxNTJjNDVjOWRhNTg2Yjgw
15
+ MTljYjc0YzFhNDUwN2ExZGZjNjVmM2I4OTFhZjNkZTVmNjU4Mjg=
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
4
+ - 2.2.1
5
+ - 2.2.2
6
+ before_script: sudo redis-server /etc/redis/redis.conf
7
+ before_install:
8
+ - gem install bundler
9
+ script: bundle exec rspec
10
+ deploy:
11
+ provider: rubygems
12
+ api_key:
13
+ secure: MWXk12XXWJ/Zz44uS/zrPVYM3wTyel9DYciInGFea5ZetJqnjn10CcNXAhKONvmgjT1EGz6yQnx1JicN9IeQ/OeRZsTArIpAeoYBVDQg4tlrHHVQAOEqr9MVrskIYcMdRttrpmHnzoRuNdWZkCG/pvE6KM3V0sOaXA+2FUfgMOU=
14
+ gem: cache_for
15
+ on:
16
+ tags: true
17
+ repo: westfieldlabs/cache_for
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cache_for.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'simplecov'
8
+ end
@@ -0,0 +1,74 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cache_for (1.1.0)
5
+ redis
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ celluloid (0.15.2)
11
+ timers (~> 1.1.0)
12
+ chronic_duration (0.10.2)
13
+ numerizer (~> 0.1.1)
14
+ coderay (1.1.0)
15
+ diff-lcs (1.2.5)
16
+ docile (1.1.0)
17
+ ffi (1.9.3)
18
+ formatador (0.2.4)
19
+ guard (2.2.4)
20
+ formatador (>= 0.2.4)
21
+ listen (~> 2.1)
22
+ lumberjack (~> 1.0)
23
+ pry (>= 0.9.12)
24
+ thor (>= 0.18.1)
25
+ guard-rspec (4.0.4)
26
+ guard (>= 2.1.1)
27
+ rspec (~> 2.14)
28
+ listen (2.2.0)
29
+ celluloid (>= 0.15.2)
30
+ rb-fsevent (>= 0.9.3)
31
+ rb-inotify (>= 0.9)
32
+ lumberjack (1.0.4)
33
+ method_source (0.8.2)
34
+ multi_json (1.8.2)
35
+ numerizer (0.1.1)
36
+ pry (0.9.12.4)
37
+ coderay (~> 1.0)
38
+ method_source (~> 0.8)
39
+ slop (~> 3.4)
40
+ rake (10.1.0)
41
+ rb-fsevent (0.9.3)
42
+ rb-inotify (0.9.2)
43
+ ffi (>= 0.5.0)
44
+ redis (3.0.6)
45
+ rspec (2.14.1)
46
+ rspec-core (~> 2.14.0)
47
+ rspec-expectations (~> 2.14.0)
48
+ rspec-mocks (~> 2.14.0)
49
+ rspec-core (2.14.7)
50
+ rspec-expectations (2.14.4)
51
+ diff-lcs (>= 1.1.3, < 2.0)
52
+ rspec-mocks (2.14.4)
53
+ simplecov (0.8.2)
54
+ docile (~> 1.1.0)
55
+ multi_json
56
+ simplecov-html (~> 0.8.0)
57
+ simplecov-html (0.8.0)
58
+ slop (3.4.7)
59
+ spec (5.0.19)
60
+ chronic_duration (~> 0.10.2)
61
+ thor (0.18.1)
62
+ timers (1.1.0)
63
+
64
+ PLATFORMS
65
+ ruby
66
+
67
+ DEPENDENCIES
68
+ bundler (~> 1.3)
69
+ cache_for!
70
+ guard
71
+ guard-rspec
72
+ rake
73
+ simplecov
74
+ spec
@@ -0,0 +1,7 @@
1
+ guard :rspec, all_on_start: true, all_after_pass: true, :cli => "--colour --format nested" do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
6
+ end
7
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Mell
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.
@@ -0,0 +1,26 @@
1
+ # CacheFor
2
+
3
+ A simple wrapper around a redis store to implement keys with a timestamp.
4
+
5
+ The "For" in CacheFor refers to 1) the content labeled by the key name, and 2) the cache duration.
6
+
7
+ ## Installation
8
+ Ruby ~>2.0.0 required.
9
+
10
+ Add this gem to your application's Gemfile:
11
+
12
+ gem 'cache_for'
13
+
14
+ ## Usage
15
+ In your app, wherever you need some caching sweetness
16
+
17
+ CacheForApp = CacheFor::Base.new()
18
+ values = CacheForApp.fetch('Product-options') { Product.all.collect {|product| [product.name, product.id]} }
19
+
20
+ Optionally, set a redis endpoint
21
+
22
+ CacheFor::Base.new( 'redis://localhost:6379' )
23
+
24
+ Optionally, set a default TTL
25
+
26
+ CacheFor::Base.new( default_secs: 600 )
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -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 'cache_for/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cache_for"
8
+ spec.version = CacheFor::VERSION
9
+ spec.authors = ["Michael Mell"]
10
+ spec.email = ["mike.mell@nthwave.net"]
11
+ spec.description = %q{Provide a simple interface to redis with self-expiring keys.}
12
+ spec.summary = %q{Provide a simple interface to redis with self-expiring keys.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "spec"
24
+ spec.add_development_dependency "guard"
25
+ spec.add_development_dependency "guard-rspec"
26
+
27
+ spec.add_dependency 'redis'
28
+ end
@@ -0,0 +1,5 @@
1
+ require "cache_for/version"
2
+ require "cache_for/base"
3
+
4
+ module CacheFor
5
+ end
@@ -0,0 +1,74 @@
1
+ require 'cache_for'
2
+ require 'time'
3
+ require 'redis'
4
+ require 'uri'
5
+
6
+ module CacheFor
7
+
8
+ class Base
9
+ attr_accessor :for_seconds
10
+ attr_accessor :redis_store
11
+
12
+ DefaultSeconds = 600 # 10 minutes
13
+ CacheMiss = nil
14
+
15
+ # When redis_uri == nil, Redis gem will use its own
16
+ # default url, typically redis://locahost:6379.
17
+ def initialize(redis_uri = nil, default_seconds: Base::DefaultSeconds)
18
+ @for_seconds = default_seconds
19
+ @redis_store = Redis.new url: redis_uri
20
+ end
21
+
22
+ def get(name, seconds = nil)
23
+ begin
24
+ if found = @redis_store.get(key_for(name, seconds))
25
+ puts "cache hit #{key_for(name, seconds)}"
26
+ found
27
+ end
28
+ rescue
29
+ puts "cache miss #{key_for(name, seconds)}"
30
+ self.class::CacheMiss
31
+ end
32
+ end
33
+ alias_method :read, :get
34
+
35
+ def set(name, value, seconds = nil)
36
+ begin
37
+ @redis_store.set(key_for(name, seconds), value)
38
+ rescue
39
+ end
40
+ end
41
+ alias_method :write, :set
42
+
43
+ def expire(name, seconds = nil)
44
+ begin
45
+ @redis_store.expire(key_for(name, seconds))
46
+ rescue
47
+ end
48
+ end
49
+
50
+ def cache_time(seconds = nil)
51
+ seconds ||= for_seconds
52
+ # a time integer that remains unchanging for <seconds> seconds
53
+ # rounds down to nearest multiple of seconds
54
+ (seconds * (Time.now.to_i / seconds).to_i)
55
+ end
56
+
57
+ def key_for(name, seconds = nil)
58
+ "#{name}#{cache_time(seconds)}"
59
+ end
60
+
61
+ def fetch(name, seconds = nil)
62
+ if (cached = get(name, seconds)) != self.class::CacheMiss
63
+ cached
64
+ else
65
+ new_value = yield
66
+ set(name, new_value, seconds)
67
+ expire(name, seconds)
68
+ new_value
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,3 @@
1
+ module CacheFor
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+ require 'cache_for'
3
+
4
+ describe CacheFor::Base do
5
+
6
+ describe "can read" do
7
+ subject { CacheFor::Base.new } # the test environment must have a redis instance running on the default localhost:6379
8
+ let(:now) { Time.now.to_s }
9
+ let(:key) {__FILE__}
10
+
11
+ it "what it wrote" do
12
+ subject.write(key, now)
13
+ subject.read(key).should == now
14
+ end
15
+
16
+ it "will not read what in did not write" do
17
+ subject.read('aoue').should == subject.class::CacheMiss
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ require "spec_helper"
2
+ require 'cache_for/base'
3
+
4
+ shared_examples "cache_time is" do |secs, cache_time|
5
+ before {
6
+ static_time.now.stub(:to_i) { secs }
7
+ }
8
+
9
+ it "#{cache_time} when time is #{secs}" do
10
+ CacheFor::Base.new('redis://redis.example.com', default_seconds: duration).cache_time.should == cache_time
11
+ end
12
+ end
13
+
14
+ describe 'CacheFor' do
15
+ describe "#new" do
16
+ context "with nil url" do
17
+ subject { CacheFor::Base.new.redis_store.client }
18
+ its(:scheme) { should eq 'redis' }
19
+ its(:host) { should eq '127.0.0.1' }
20
+ its(:port) { should eq 6379 }
21
+ its(:db) { should eq 0 }
22
+ end
23
+
24
+ context "with url" do
25
+ let(:url) { 'redis://dummy.com:6666/6' }
26
+ subject { CacheFor::Base.new(url).redis_store.client }
27
+ its(:scheme) { should eq 'redis' }
28
+ its(:host) { should eq 'dummy.com' }
29
+ its(:port) { should eq 6666 }
30
+ its(:db) { should eq 6 }
31
+ end
32
+ end
33
+ end
34
+
35
+ describe 'CacheFor#cache_time' do
36
+
37
+ describe "cache_time" do
38
+ let(:static_time) { double("StaticTime") }
39
+
40
+ before {
41
+ stub_const("Time", static_time)
42
+ static_time.stub(:now) { static_time }
43
+ }
44
+
45
+ it "Time.now.to_i should be stubbable" do
46
+ static_time.now.stub(:to_i) { 1000 }
47
+ Time.now.to_i.should == 1000
48
+ end
49
+
50
+ context "when duration is 10" do
51
+ let(:duration) { 10 }
52
+
53
+ it_behaves_like "cache_time is", 1011, 1010
54
+ it_behaves_like "cache_time is", 1001, 1000
55
+ it_behaves_like "cache_time is", 1000, 1000
56
+ it_behaves_like "cache_time is", 999, 990
57
+ it_behaves_like "cache_time is", 550, 550
58
+ end
59
+
60
+ context "when duration is 100" do
61
+ let(:duration) { 100 }
62
+
63
+ it_behaves_like "cache_time is", 1101, 1100
64
+ it_behaves_like "cache_time is", 1001, 1000
65
+ it_behaves_like "cache_time is", 1000, 1000
66
+ it_behaves_like "cache_time is", 999, 900
67
+ it_behaves_like "cache_time is", 550, 500
68
+ end
69
+
70
+ context "when duration is 600" do
71
+ let(:duration) { 600 }
72
+
73
+ it_behaves_like "cache_time is", 1601, 1200
74
+ it_behaves_like "cache_time is", 1001, 600
75
+ it_behaves_like "cache_time is", 1000, 600
76
+ it_behaves_like "cache_time is", 999, 600
77
+ it_behaves_like "cache_time is", 550, 0
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,15 @@
1
+ require 'json'
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+
10
+ # Run specs in random order to surface order dependencies. If you find an
11
+ # order dependency and want to debug it, you can fix the order by providing
12
+ # the seed, which is printed after each run.
13
+ # --seed 1234
14
+ config.order = 'default'
15
+ end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'cache_for/rack'
4
+
5
+ class HelloCacheFor
6
+
7
+ def new(redis_uri)
8
+ @cache_for = CacheFor::Base.new(redis_uri)
9
+ end
10
+
11
+ def call(env)
12
+
13
+ [200, {"Content-Type" => "text/html"}, "Hello Rack!"]
14
+ end
15
+ end
16
+
17
+ Rack::Handler::Mongrel.run HelloCacheFor.new, :Port => 9292
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cache_for
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Mell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: spec
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: guard
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: guard-rspec
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: redis
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Provide a simple interface to redis with self-expiring keys.
98
+ email:
99
+ - mike.mell@nthwave.net
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - .travis.yml
107
+ - Gemfile
108
+ - Gemfile.lock
109
+ - Guardfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - cache_for.gemspec
114
+ - lib/cache_for.rb
115
+ - lib/cache_for/base.rb
116
+ - lib/cache_for/version.rb
117
+ - spec/lib/cache_for/base_spec.rb
118
+ - spec/lib/cache_for_spec.rb
119
+ - spec/spec_helper.rb
120
+ - spec/support/rack_application.rb
121
+ homepage: ''
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.4.5
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Provide a simple interface to redis with self-expiring keys.
145
+ test_files:
146
+ - spec/lib/cache_for/base_spec.rb
147
+ - spec/lib/cache_for_spec.rb
148
+ - spec/spec_helper.rb
149
+ - spec/support/rack_application.rb