adapter-redis 0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in adapter-redis.gemspec
4
+ gemspec
5
+
6
+ group(:development) do
7
+ gem 'rspec', '~> 2.3'
8
+ gem 'log_buddy', '~> 0.5.0'
9
+ gem 'timecop', '~> 0.3.5'
10
+ gem 'SystemTimer', '~> 1.2.1'
11
+ gem 'i18n', '0.5.0'
12
+ gem 'activesupport', '~> 3', :require => 'active_support'
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ adapter-redis (0.5)
5
+ adapter (~> 0.5)
6
+ redis
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ SystemTimer (1.2.1)
12
+ activesupport (3.0.3)
13
+ adapter (0.5.1)
14
+ diff-lcs (1.1.2)
15
+ i18n (0.5.0)
16
+ log_buddy (0.5.0)
17
+ redis (2.1.1)
18
+ rspec (2.4.0)
19
+ rspec-core (~> 2.4.0)
20
+ rspec-expectations (~> 2.4.0)
21
+ rspec-mocks (~> 2.4.0)
22
+ rspec-core (2.4.0)
23
+ rspec-expectations (2.4.0)
24
+ diff-lcs (~> 1.1.2)
25
+ rspec-mocks (2.4.0)
26
+ timecop (0.3.5)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ SystemTimer (~> 1.2.1)
33
+ activesupport (~> 3)
34
+ adapter (~> 0.5)
35
+ adapter-redis!
36
+ i18n (= 0.5.0)
37
+ log_buddy (~> 0.5.0)
38
+ redis
39
+ rspec (~> 2.3)
40
+ timecop (~> 0.3.5)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Newtoy, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,13 @@
1
+ = adapter-redis
2
+
3
+ Redis adapter for adapter gem.
4
+
5
+ See examples/ or specs/ for usage.
6
+
7
+ == Note on Patches/Pull Requests
8
+
9
+ * Fork the project.
10
+ * Make your feature addition or bug fix.
11
+ * Add tests for it. This is important so we don't break it in a future version unintentionally.
12
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine, but bump version in a commit by itself so we can ignore when we pull)
13
+ * Send us a pull request. Bonus points for topic branches.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+
7
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "adapter/redis/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "adapter-redis"
7
+ s.version = Adapter::Redis::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["John Nunemaker"]
10
+ s.email = ["nunemaker@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Adapter for redis}
13
+ s.description = %q{Adapter for redis}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency 'adapter', '~> 0.5.1'
21
+ s.add_dependency 'redis'
22
+ end
data/examples/redis.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'pathname'
3
+
4
+ root_path = Pathname(__FILE__).dirname.join('..').expand_path
5
+ lib_path = root_path.join('lib')
6
+ $:.unshift(lib_path)
7
+
8
+ require 'adapter/redis'
9
+
10
+ client = Redis.new
11
+ adapter = Adapter[:redis].new(client)
12
+ adapter.clear
13
+
14
+ adapter.write('foo', 'bar')
15
+ puts 'Should be bar: ' + adapter.read('foo').inspect
16
+
17
+ adapter.delete('foo')
18
+ puts 'Should be nil: ' + adapter.read('foo').inspect
19
+
20
+ adapter.write('foo', 'bar')
21
+ adapter.clear
22
+ puts 'Should be nil: ' + adapter.read('foo').inspect
23
+
24
+ puts 'Should be bar: ' + adapter.fetch('foo', 'bar')
25
+ puts 'Should be bar: ' + adapter.read('foo')
@@ -0,0 +1,68 @@
1
+ require 'adapter'
2
+ require 'redis'
3
+
4
+ module Adapter
5
+ module Redis
6
+ def read(key)
7
+ decode(client.get(key_for(key)))
8
+ end
9
+
10
+ def write(key, value)
11
+ client.set(key_for(key), encode(value))
12
+ end
13
+
14
+ def delete(key)
15
+ read(key).tap { client.del(key_for(key)) }
16
+ end
17
+
18
+ def clear
19
+ client.flushdb
20
+ end
21
+
22
+ # Pretty much stolen from redis objects
23
+ # http://github.com/nateware/redis-objects/blob/master/lib/redis/lock.rb
24
+ def lock(name, options={}, &block)
25
+ key = name.to_s
26
+ start = Time.now
27
+ acquired_lock = false
28
+ expiration = nil
29
+ expires_in = options.fetch(:expiration, 1)
30
+ timeout = options.fetch(:timeout, 5)
31
+
32
+ while (Time.now - start) < timeout
33
+ expiration = generate_expiration(expires_in)
34
+ acquired_lock = client.setnx(key, expiration)
35
+ break if acquired_lock
36
+
37
+ old_expiration = client.get(key).to_f
38
+
39
+ if old_expiration < Time.now.to_f
40
+ expiration = generate_expiration(expires_in)
41
+ old_expiration = client.getset(key, expiration).to_f
42
+
43
+ if old_expiration < Time.now.to_f
44
+ acquired_lock = true
45
+ break
46
+ end
47
+ end
48
+
49
+ sleep 0.1
50
+ end
51
+
52
+ raise(LockTimeout.new(name, timeout)) unless acquired_lock
53
+
54
+ begin
55
+ yield
56
+ ensure
57
+ client.del(key) if expiration > Time.now.to_f
58
+ end
59
+ end
60
+
61
+ # Defaults expiration to 1
62
+ def generate_expiration(expiration)
63
+ (Time.now + (expiration || 1).to_f).to_f
64
+ end
65
+ end
66
+ end
67
+
68
+ Adapter.define(:redis, Adapter::Redis)
@@ -0,0 +1,5 @@
1
+ module Adapter
2
+ module Redis
3
+ VERSION = "0.5"
4
+ end
5
+ end
data/log/test.log ADDED
@@ -0,0 +1 @@
1
+ # Logfile created on Tue Jan 25 22:18:39 -0500 2011 by logger.rb
data/spec/helper.rb ADDED
@@ -0,0 +1,26 @@
1
+ $:.unshift(File.expand_path('../../lib', __FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ Bundler.require(:default, :development)
7
+
8
+ require 'pathname'
9
+ require 'logger'
10
+
11
+ root_path = Pathname(__FILE__).dirname.join('..').expand_path
12
+ lib_path = root_path.join('lib')
13
+ log_path = root_path.join('log')
14
+ log_path.mkpath
15
+
16
+ require 'adapter/spec/an_adapter'
17
+ require 'adapter/spec/marshal_adapter'
18
+ require 'adapter/spec/json_adapter'
19
+ require 'adapter/spec/types'
20
+
21
+ logger = Logger.new(log_path.join('test.log'))
22
+ LogBuddy.init(:logger => logger)
23
+
24
+ Rspec.configure do |c|
25
+
26
+ end
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+ require 'adapter/redis'
3
+
4
+ describe "Redis adapter" do
5
+ before do
6
+ @client = Redis.new
7
+ @adapter = Adapter[:redis].new(@client)
8
+ @adapter.clear
9
+ end
10
+
11
+ let(:adapter) { @adapter }
12
+ let(:client) { @client }
13
+
14
+ it_should_behave_like 'a marshaled adapter'
15
+
16
+ describe "#lock" do
17
+ let(:lock_key) { :add_game }
18
+
19
+ it "defaults expiration to 1" do
20
+ now = Time.mktime(2010, 10, 10, 5, 5, 5)
21
+ Timecop.freeze(now) do
22
+ expiration = now.to_i + 1
23
+ client.should_receive(:setnx).with(lock_key.to_s, expiration).and_return(true)
24
+ adapter.lock(lock_key) { }
25
+ end
26
+ end
27
+
28
+ it "allows setting expiration" do
29
+ now = Time.mktime(2010, 10, 10, 5, 5, 5)
30
+ Timecop.freeze(now) do
31
+ expiration = now.to_i + 5
32
+ client.should_receive(:setnx).with(lock_key.to_s, expiration).and_return(true)
33
+ adapter.lock(lock_key, :expiration => 5) { }
34
+ end
35
+ end
36
+
37
+ describe "with no existing lock" do
38
+ it "acquires lock, performs block, and clears lock" do
39
+ result = false
40
+ adapter.lock(lock_key) { result = true }
41
+
42
+ result.should be_true
43
+ adapter.read(lock_key).should be_nil
44
+ end
45
+ end
46
+
47
+ describe "with lock set" do
48
+ it "waits for unlock, performs block, and clears lock" do
49
+ result = false
50
+ client.set(lock_key.to_s, adapter.generate_expiration(1))
51
+ adapter.lock(lock_key, :timeout => 2) { result = true }
52
+
53
+ result.should be_true
54
+ adapter.read(lock_key).should be_nil
55
+ end
56
+ end
57
+
58
+ describe "with lock set that does not expire before timeout" do
59
+ it "raises lock timeout error" do
60
+ result = false
61
+ client.set(lock_key.to_s, adapter.generate_expiration(2))
62
+
63
+ lambda do
64
+ adapter.lock(lock_key, :timeout => 1) { result = true }
65
+ end.should raise_error(Adapter::LockTimeout, 'Timeout on lock add_game exceeded 1 sec')
66
+ end
67
+ end
68
+ end
69
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adapter-redis
3
+ version: !ruby/object:Gem::Version
4
+ hash: 1
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ version: "0.5"
10
+ platform: ruby
11
+ authors:
12
+ - John Nunemaker
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-25 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: adapter
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 9
29
+ segments:
30
+ - 0
31
+ - 5
32
+ - 1
33
+ version: 0.5.1
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: redis
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ description: Adapter for redis
51
+ email:
52
+ - nunemaker@gmail.com
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files: []
58
+
59
+ files:
60
+ - .gitignore
61
+ - Gemfile
62
+ - Gemfile.lock
63
+ - LICENSE
64
+ - README.rdoc
65
+ - Rakefile
66
+ - adapter-redis.gemspec
67
+ - examples/redis.rb
68
+ - lib/adapter/redis.rb
69
+ - lib/adapter/redis/version.rb
70
+ - log/test.log
71
+ - spec/helper.rb
72
+ - spec/redis_spec.rb
73
+ has_rdoc: true
74
+ homepage: ""
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options: []
79
+
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 3
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 1.3.7
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Adapter for redis
107
+ test_files:
108
+ - spec/helper.rb
109
+ - spec/redis_spec.rb