wolverine 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 ADDED
@@ -0,0 +1,52 @@
1
+ # Wolverine
2
+
3
+ Wolverine is a simple library to allow you to manage and run redis server-side lua scripts from a rails app, or other ruby code.
4
+
5
+ ## What are you talking about?
6
+
7
+ Redis versions 2.6 and up allow lua scripts to be run on the server that execute atomically and very, very quickly.
8
+
9
+ This is really, really cool.
10
+
11
+ Wolverine is a wrapper around that functionality, to package it up in a format more familiar to a Rails codebase.
12
+
13
+ ## How do I use it?
14
+
15
+ 1) Make sure you have redis 2.6 or higher installed. As of now, that means compiling from source.
16
+
17
+ git clone https://github.com/antirez/redis.git
18
+ cd redis && make
19
+ ./src/redis-server
20
+
21
+ 2) Add wolverine to your gemfile
22
+
23
+ gem 'wolverine'
24
+
25
+ 3) Add your lua scripts to `app/redis`
26
+
27
+ # app/redis/util/mexists.lua
28
+ local exists = {}
29
+ local existence
30
+ for _, key in ipairs(KEYS) do
31
+ table.insert(exists, redis.call('exists', key))
32
+ end
33
+ return exists
34
+
35
+ 4) Call from your code:
36
+
37
+ Wolverine.call('util/mexists', 'key1', 'key2', 'key3') #=> [0, 1, 0]
38
+
39
+ ## More information
40
+
41
+ For more information on scripting redis with lua, refer to redis' excellent documentation: http://redis.io/commands/eval
42
+
43
+ ## License
44
+
45
+ Copyright (C) 2012 Shopify
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52
+
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Wolverine
2
+
3
+ Wolverine is a simple library to allow you to manage and run redis server-side lua scripts from a rails app, or other ruby code.
4
+
5
+ ## What are you talking about?
6
+
7
+ Redis versions 2.6 and up allow lua scripts to be run on the server that execute atomically and very, very quickly.
8
+
9
+ This is really, really cool.
10
+
11
+ Wolverine is a wrapper around that functionality, to package it up in a format more familiar to a Rails codebase.
12
+
13
+ ## How do I use it?
14
+
15
+ 1) Make sure you have redis 2.6 or higher installed. As of now, that means compiling from source.
16
+
17
+ git clone https://github.com/antirez/redis.git
18
+ cd redis && make
19
+ ./src/redis-server
20
+
21
+ 2) Add wolverine to your gemfile
22
+
23
+ gem 'wolverine'
24
+
25
+ 3) Add your lua scripts to `app/redis`
26
+
27
+ -- app/redis/util/mexists.lua
28
+ local exists = {}
29
+ local existence
30
+ for _, key in ipairs(KEYS) do
31
+ table.insert(exists, redis.call('exists', key))
32
+ end
33
+ return exists
34
+
35
+ 4) Call from your code:
36
+
37
+ Wolverine.call('util/mexists', 'key1', 'key2', 'key3') #=> [0, 1, 0]
38
+
39
+ ## More information
40
+
41
+ For more information on scripting redis with lua, refer to redis' excellent documentation: http://redis.io/commands/eval
42
+
43
+ ## License
44
+
45
+ Copyright (C) 2012 Shopify
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52
+
data/lib/wolverine.rb CHANGED
@@ -1,46 +1,25 @@
1
- require "wolverine/version"
2
1
  require 'redis'
3
2
 
4
- module Wolverine
5
- def self.script_path
6
- Rails.root + 'app/redis'
7
- end
3
+ require "wolverine/version"
4
+ require 'wolverine/configuration'
5
+ require 'wolverine/script'
8
6
 
9
- def self.call(file, *args)
10
- file << ".lua" unless file =~ /\.lua$/
11
- LuaFile.new(script_path + file).call(redis, *args)
7
+ module Wolverine
8
+ def self.config
9
+ @config ||= Configuration.new
12
10
  end
13
11
 
14
12
  def self.redis
15
- $redis ||= Redis.new
13
+ config.redis
16
14
  end
17
15
 
18
- class LuaFile
19
- attr_reader :content, :digest
20
- def initialize file
21
- @content = load_lua file
22
- @digest = Digest::SHA1.hexdigest @content
23
- end
24
-
25
- def call redis, *args
26
- run_evalsha redis, *args
27
- rescue => e
28
- e.message =~ /NOSCRIPT/ ? run_eval(redis, *args) : raise
29
- end
30
-
31
- private
32
-
33
- def run_evalsha redis, *args
34
- redis.evalsha digest, args.size, *args
35
- end
36
-
37
- def run_eval redis, *args
38
- redis.eval content, args.size, *args
39
- end
16
+ def self.call(file, *args)
17
+ Script.new(full_path(file)).call(redis, *args)
18
+ end
40
19
 
41
- def load_lua file
42
- File.read file
43
- end
20
+ def self.full_path(file)
21
+ file << ".lua" unless file =~ /\.lua$/
22
+ config.script_path + file
44
23
  end
45
24
 
46
25
  end
@@ -0,0 +1,11 @@
1
+ module Wolverine
2
+ class Configuration < Struct.new(:redis, :script_path)
3
+ def redis
4
+ super || @redis ||= Redis.new
5
+ end
6
+
7
+ def script_path
8
+ super || @script_path ||= Rails.root + 'app/redis'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ module Wolverine
2
+ class Script
3
+ attr_reader :content, :digest
4
+ def initialize file
5
+ @content = load_lua file
6
+ @digest = Digest::SHA1.hexdigest @content
7
+ end
8
+
9
+ def call redis, *args
10
+ run_evalsha redis, *args
11
+ rescue => e
12
+ e.message =~ /NOSCRIPT/ ? run_eval(redis, *args) : raise
13
+ end
14
+
15
+ private
16
+
17
+ def run_evalsha redis, *args
18
+ redis.evalsha digest, args.size, *args
19
+ end
20
+
21
+ def run_eval redis, *args
22
+ redis.eval content, args.size, *args
23
+ end
24
+
25
+ def load_lua file
26
+ File.read file
27
+ end
28
+
29
+ end
30
+ end
31
+
@@ -1,3 +1,3 @@
1
1
  module Wolverine
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,5 @@
1
+ require 'minitest/autorun'
2
+ require 'mocha'
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+ require 'wolverine'
@@ -0,0 +1,35 @@
1
+ require_relative '../test_helper'
2
+ require 'pathname'
3
+
4
+ module Rails
5
+ def self.root
6
+ Pathname.new('foo')
7
+ end
8
+ end
9
+
10
+ module Wolverine
11
+ class ConfigurationTest < MiniTest::Unit::TestCase
12
+
13
+ def test_default_redis
14
+ assert_instance_of Redis, Wolverine::Configuration.new.redis
15
+ end
16
+
17
+ def test_default_script_path
18
+ actual = Wolverine::Configuration.new.script_path
19
+ assert_equal Pathname.new('foo/app/redis'), actual
20
+ end
21
+
22
+ def test_setting_redis
23
+ config = Wolverine::Configuration.new
24
+ config.redis = :foo
25
+ assert_equal :foo, config.redis
26
+ end
27
+
28
+ def test_setting_script_path
29
+ config = Wolverine::Configuration.new
30
+ config.script_path = :foo
31
+ assert_equal :foo, config.script_path
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ require_relative '../test_helper'
2
+ require 'digest/sha1'
3
+
4
+ module Wolverine
5
+ class ScriptTest < MiniTest::Unit::TestCase
6
+ CONTENT = "return 1"
7
+ DIGEST = Digest::SHA1.hexdigest(CONTENT)
8
+
9
+ def setup
10
+ Wolverine::Script.any_instance.stubs(load_lua: CONTENT)
11
+ end
12
+
13
+ def script
14
+ @script ||= Wolverine::Script.new('file1')
15
+ end
16
+
17
+ def test_digest_and_content
18
+ content = "return 1"
19
+ assert_equal CONTENT, script.content
20
+ assert_equal DIGEST, script.digest
21
+ end
22
+
23
+ def test_call_with_cache_hit
24
+ tc = self
25
+ redis = Class.new do
26
+ define_method(:evalsha) do |digest, size, *args|
27
+ tc.assert_equal DIGEST, digest
28
+ tc.assert_equal 2, size
29
+ tc.assert_equal [:a, :b], args
30
+ end
31
+ end
32
+ script.call(redis.new, :a, :b)
33
+ end
34
+
35
+ def test_call_with_cache_miss
36
+ tc = self
37
+ redis = Class.new do
38
+ define_method(:evalsha) do |*|
39
+ raise "NOSCRIPT No matching script. Please use EVAL."
40
+ end
41
+ define_method(:eval) do |content, size, *args|
42
+ tc.assert_equal CONTENT, content
43
+ tc.assert_equal 2, size
44
+ tc.assert_equal [:a, :b], args
45
+ end
46
+ end
47
+ script.call(redis.new, :a, :b)
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'test_helper'
2
+
3
+ class WolverineTest < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ Wolverine.config.redis = :redis
7
+ Wolverine.config.script_path = Pathname.new('foo')
8
+ end
9
+
10
+ def test_adds_extension_if_none_present
11
+ assert_equal Pathname.new('foo/bar.lua'), Wolverine.full_path('bar')
12
+ end
13
+
14
+ def test_redis
15
+ assert_equal :redis, Wolverine.redis
16
+ end
17
+
18
+ def test_call
19
+ script = stub
20
+ script.expects(:call).with(:redis, :a, :b).returns(:return)
21
+ Wolverine::Script.expects(:new).with(Pathname.new('foo/bar.lua')).returns(script)
22
+ assert_equal :return, Wolverine.call('bar', :a, :b)
23
+ end
24
+
25
+ end
data/wolverine.gemspec CHANGED
@@ -19,4 +19,6 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_runtime_dependency 'redis'
22
+ s.add_development_dependency 'mocha'
23
+ s.add_development_dependency 'minitest'
22
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wolverine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-03-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &70192619258840 !ruby/object:Gem::Requirement
16
+ requirement: &70114961106680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,29 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70192619258840
24
+ version_requirements: *70114961106680
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ requirement: &70114961105880 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70114961105880
36
+ - !ruby/object:Gem::Dependency
37
+ name: minitest
38
+ requirement: &70114961105380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70114961105380
25
47
  description: Wolverine provides a simple way to run server-side redis scripts from
26
48
  a rails app
27
49
  email:
@@ -32,9 +54,17 @@ extra_rdoc_files: []
32
54
  files:
33
55
  - .gitignore
34
56
  - Gemfile
57
+ - README
58
+ - README.md
35
59
  - Rakefile
36
60
  - lib/wolverine.rb
61
+ - lib/wolverine/configuration.rb
62
+ - lib/wolverine/script.rb
37
63
  - lib/wolverine/version.rb
64
+ - test/test_helper.rb
65
+ - test/wolverine/configuration_test.rb
66
+ - test/wolverine/script_test.rb
67
+ - test/wolverine_test.rb
38
68
  - wolverine.gemspec
39
69
  homepage: ''
40
70
  licenses: []
@@ -61,4 +91,8 @@ signing_key:
61
91
  specification_version: 3
62
92
  summary: Wolverine provides a simple way to run server-side redis scripts from a rails
63
93
  app
64
- test_files: []
94
+ test_files:
95
+ - test/test_helper.rb
96
+ - test/wolverine/configuration_test.rb
97
+ - test/wolverine/script_test.rb
98
+ - test/wolverine_test.rb