redis-actionpack-json 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.gitignore +15 -0
  2. data/.travis.yml +7 -0
  3. data/CHANGELOG +450 -0
  4. data/README.md +23 -0
  5. data/redis-actionpack-json/.gitignore +4 -0
  6. data/redis-actionpack-json/Gemfile +6 -0
  7. data/redis-actionpack-json/MIT-LICENSE +20 -0
  8. data/redis-actionpack-json/Rakefile +8 -0
  9. data/redis-actionpack-json/lib/action_dispatch/middleware/session/redis_store_json.rb +24 -0
  10. data/redis-actionpack-json/lib/redis-actionpack-json.rb +4 -0
  11. data/redis-actionpack-json/lib/redis/actionpack/version.rb +5 -0
  12. data/redis-actionpack-json/redis-actionpack-json.gemspec +32 -0
  13. data/redis-actionpack-json/test/dummy/.gitignore +1 -0
  14. data/redis-actionpack-json/test/dummy/Rakefile +7 -0
  15. data/redis-actionpack-json/test/dummy/app/controllers/test_controller.rb +37 -0
  16. data/redis-actionpack-json/test/dummy/config.ru +4 -0
  17. data/redis-actionpack-json/test/dummy/config/application.rb +29 -0
  18. data/redis-actionpack-json/test/dummy/config/boot.rb +10 -0
  19. data/redis-actionpack-json/test/dummy/config/environment.rb +5 -0
  20. data/redis-actionpack-json/test/dummy/config/initializers/secret_token.rb +7 -0
  21. data/redis-actionpack-json/test/dummy/config/initializers/session_store.rb +11 -0
  22. data/redis-actionpack-json/test/dummy/config/routes.rb +3 -0
  23. data/redis-actionpack-json/test/dummy/script/rails +6 -0
  24. data/redis-actionpack-json/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +10 -0
  25. data/redis-actionpack-json/test/integration/redis_store_integration_test.rb +130 -0
  26. data/redis-actionpack-json/test/integration/redis_store_json_integration_test.rb +130 -0
  27. data/redis-actionpack-json/test/redis/actionpack/version_test.rb +7 -0
  28. data/redis-actionpack-json/test/test_helper.rb +23 -0
  29. data/redis-rack-json/.gitignore +5 -0
  30. data/redis-rack-json/Gemfile +5 -0
  31. data/redis-rack-json/MIT-LICENSE +20 -0
  32. data/redis-rack-json/Rakefile +8 -0
  33. data/redis-rack-json/lib/rack/session/redis.rb +69 -0
  34. data/redis-rack-json/lib/redis-rack-json.rb +3 -0
  35. data/redis-rack-json/lib/redis/rack/version.rb +6 -0
  36. data/redis-rack-json/redis-rack-json.gemspec +29 -0
  37. data/redis-rack-json/test/rack/session/redis_test.rb +289 -0
  38. data/redis-rack-json/test/redis/rack/version_test.rb +7 -0
  39. data/redis-rack-json/test/test_helper.rb +7 -0
  40. data/redis-store-json/Gemfile +4 -0
  41. data/redis-store-json/MIT-LICENSE +20 -0
  42. data/redis-store-json/Rakefile +7 -0
  43. data/redis-store-json/lib/redis-store-json.rb +11 -0
  44. data/redis-store-json/lib/redis/distributed_store.rb +46 -0
  45. data/redis-store-json/lib/redis/factory.rb +41 -0
  46. data/redis-store-json/lib/redis/store.rb +47 -0
  47. data/redis-store-json/lib/redis/store/interface.rb +21 -0
  48. data/redis-store-json/lib/redis/store/namespace.rb +66 -0
  49. data/redis-store-json/lib/redis/store/strategy.rb +60 -0
  50. data/redis-store-json/lib/redis/store/strategy/json.rb +49 -0
  51. data/redis-store-json/lib/redis/store/strategy/json_session.rb +67 -0
  52. data/redis-store-json/lib/redis/store/strategy/marshal.rb +16 -0
  53. data/redis-store-json/lib/redis/store/strategy/yaml.rb +16 -0
  54. data/redis-store-json/lib/redis/store/ttl.rb +37 -0
  55. data/redis-store-json/lib/redis/store/version.rb +5 -0
  56. data/redis-store-json/lib/tasks/redis.tasks.rb +167 -0
  57. data/redis-store-json/redis-store-json.gemspec +29 -0
  58. data/redis-store-json/test/config/node-one.conf +46 -0
  59. data/redis-store-json/test/config/node-two.conf +46 -0
  60. data/redis-store-json/test/config/redis.conf +46 -0
  61. data/redis-store-json/test/redis/distributed_store_test.rb +53 -0
  62. data/redis-store-json/test/redis/factory_test.rb +120 -0
  63. data/redis-store-json/test/redis/store/interface_test.rb +27 -0
  64. data/redis-store-json/test/redis/store/namespace_test.rb +103 -0
  65. data/redis-store-json/test/redis/store/strategy/json_session_test.rb +160 -0
  66. data/redis-store-json/test/redis/store/strategy/json_test.rb +108 -0
  67. data/redis-store-json/test/redis/store/strategy/marshal_test.rb +121 -0
  68. data/redis-store-json/test/redis/store/strategy/yaml_test.rb +105 -0
  69. data/redis-store-json/test/redis/store/ttl_test.rb +107 -0
  70. data/redis-store-json/test/redis/store/version_test.rb +7 -0
  71. data/redis-store-json/test/redis/store_test.rb +45 -0
  72. data/redis-store-json/test/test_helper.rb +22 -0
  73. metadata +279 -0
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ describe Redis::Rack::VERSION do
4
+ it "must be equal to 1.4.2" do
5
+ Redis::Rack::VERSION.must_equal '1.4.2'
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ Bundler.setup
2
+ gem 'minitest'
3
+ require 'minitest/spec'
4
+ require 'minitest/autorun'
5
+ require 'mocha/setup'
6
+ require 'rack'
7
+ require 'rack/session/redis'
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'SystemTimer', :platform => :mri_18
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 - 2011 Luca Guidi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+ require 'rake'
4
+ require 'bundler/gem_tasks'
5
+
6
+ load 'tasks/redis.tasks.rb'
7
+ task :default => 'redis:test:suite'
@@ -0,0 +1,11 @@
1
+ require 'redis'
2
+ require 'redis/store'
3
+ require 'redis/factory'
4
+ require 'redis/distributed_store'
5
+ require 'redis/store/namespace'
6
+ require 'redis/store/version'
7
+
8
+ class Redis
9
+ class Store < self
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ require 'redis/distributed'
2
+
3
+ class Redis
4
+ class DistributedStore < Distributed
5
+ @@timeout = 5
6
+ attr_reader :ring
7
+
8
+ def initialize(addresses, options = { })
9
+ nodes = addresses.map do |address|
10
+ ::Redis::Store.new _merge_options(address, options)
11
+ end
12
+ _extend_namespace options
13
+ @ring = Redis::HashRing.new nodes
14
+ end
15
+
16
+ def nodes
17
+ ring.nodes
18
+ end
19
+
20
+ def reconnect
21
+ nodes.each {|node| node.reconnect }
22
+ end
23
+
24
+ def set(key, value, options = nil)
25
+ node_for(key).set(key, value, options)
26
+ end
27
+
28
+ def get(key, options = nil)
29
+ node_for(key).get(key, options)
30
+ end
31
+
32
+ def setnx(key, value, options = nil)
33
+ node_for(key).setnx(key, value, options)
34
+ end
35
+
36
+ private
37
+ def _extend_namespace(options)
38
+ @namespace = options[:namespace]
39
+ extend ::Redis::Store::Namespace if @namespace
40
+ end
41
+
42
+ def _merge_options(address, options)
43
+ address.merge(:timeout => options[:timeout] || @@timeout)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,41 @@
1
+ require 'uri'
2
+
3
+ class Redis
4
+ class Factory
5
+ def self.create(*redis_client_options)
6
+ redis_client_options = redis_client_options.flatten.compact.inject([]) do |result, address|
7
+ result << resolve(address)
8
+ result
9
+ end
10
+ if redis_client_options.size > 1
11
+ ::Redis::DistributedStore.new redis_client_options
12
+ else
13
+ ::Redis::Store.new redis_client_options.first || {}
14
+ end
15
+ end
16
+
17
+ def self.resolve(uri) #:api: private
18
+ if uri.is_a?(Hash)
19
+ options = uri.dup
20
+ options[:namespace] ||= options.delete(:key_prefix) # RailsSessionStore
21
+ options
22
+ else
23
+ uri = URI.parse(uri)
24
+ _, db, namespace = if uri.path
25
+ uri.path.split /\//
26
+ end
27
+
28
+ options = {
29
+ :host => uri.host,
30
+ :port => uri.port || 6379,
31
+ :password => uri.password
32
+ }
33
+
34
+ options[:db] = db.to_i if db
35
+ options[:namespace] = namespace if namespace
36
+
37
+ options
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ require 'redis/store/ttl'
2
+ require 'redis/store/interface'
3
+ require 'redis/store/strategy'
4
+
5
+ class Redis
6
+ class Store < self
7
+ include Ttl, Interface
8
+
9
+ STRATEGIES = {
10
+ :marshal => Strategy::Marshal,
11
+ :json => Strategy::Json,
12
+ :json_session => Strategy::JsonSession,
13
+ :yaml => Strategy::Yaml,
14
+ }.freeze
15
+
16
+ def initialize(options = { })
17
+ super options.delete(:redis_server)
18
+
19
+ _extend_strategy options
20
+ _extend_namespace options
21
+ end
22
+
23
+ def reconnect
24
+ @client.reconnect
25
+ end
26
+
27
+ def to_s
28
+ "Redis Client connected to #{@client.host}:#{@client.port} against DB #{@client.db}"
29
+ end
30
+
31
+ private
32
+ def _extend_strategy(options)
33
+ strategy = options[:strategy]
34
+
35
+ unless strategy === false
36
+ strategy_class = STRATEGIES[strategy] || STRATEGIES[:marshal]
37
+ extend Strategy, strategy_class
38
+ end
39
+ end
40
+
41
+ def _extend_namespace(options)
42
+ @namespace = options[:namespace]
43
+ extend Namespace if @namespace
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,21 @@
1
+ class Redis
2
+ class Store < self
3
+ module Interface
4
+ def get(key, options = nil)
5
+ super(key)
6
+ end
7
+
8
+ def set(key, value, options = nil)
9
+ super(key, value)
10
+ end
11
+
12
+ def setnx(key, value, options = nil)
13
+ super(key, value)
14
+ end
15
+
16
+ def setex(key, expiry, value, options = nil)
17
+ super(key, expiry, value)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ class Redis
2
+ class Store < self
3
+ module Namespace
4
+ def set(key, val, options = nil)
5
+ namespace(key) { |key| super(key, val, options) }
6
+ end
7
+
8
+ def setnx(key, val, options = nil)
9
+ namespace(key) { |key| super(key, val, options) }
10
+ end
11
+
12
+ def get(key, options = nil)
13
+ namespace(key) { |key| super(key, options) }
14
+ end
15
+
16
+ def exists(key)
17
+ namespace(key) { |key| super(key) }
18
+ end
19
+
20
+ def incrby(key, increment)
21
+ namespace(key) { |key| super(key, increment) }
22
+ end
23
+
24
+ def decrby(key, increment)
25
+ namespace(key) { |key| super(key, increment) }
26
+ end
27
+
28
+ def keys(pattern = "*")
29
+ namespace(pattern) { |pattern| super(pattern).map{|key| strip_namespace(key) } }
30
+ end
31
+
32
+ def del(*keys)
33
+ super *keys.map {|key| interpolate(key) } if keys.any?
34
+ end
35
+
36
+ def mget(*keys)
37
+ super *keys.map {|key| interpolate(key) } if keys.any?
38
+ end
39
+
40
+ def to_s
41
+ "#{super} with namespace #{@namespace}"
42
+ end
43
+
44
+ def flushdb
45
+ del *keys
46
+ end
47
+
48
+ private
49
+ def namespace(key)
50
+ yield interpolate(key)
51
+ end
52
+
53
+ def interpolate(key)
54
+ key.match(namespace_regexp) ? key : "#{@namespace}:#{key}"
55
+ end
56
+
57
+ def strip_namespace(key)
58
+ key.gsub namespace_regexp, ""
59
+ end
60
+
61
+ def namespace_regexp
62
+ @namespace_regexp ||= %r{^#{@namespace}\:}
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,60 @@
1
+ require 'redis/store/strategy/json'
2
+ require 'redis/store/strategy/json_session'
3
+ require 'redis/store/strategy/marshal'
4
+ require 'redis/store/strategy/yaml'
5
+
6
+ class Redis
7
+ class Store < self
8
+ module Strategy
9
+ def set(key, value, options = nil)
10
+ dump(value, options) { |value| super encode(key), encode(value), options }
11
+ end
12
+
13
+ def setnx(key, value, options = nil)
14
+ dump(value, options) { |value| super encode(key), encode(value), options }
15
+ end
16
+
17
+ def setex(key, expiry, value, options = nil)
18
+ dump(value, options) { |value| super encode(key), expiry, encode(value), options }
19
+ end
20
+
21
+ def get(key, options = nil)
22
+ load super(key), options
23
+ end
24
+
25
+ def mget(*keys)
26
+ options = keys.flatten.pop if keys.flatten.last.is_a?(Hash)
27
+ super(*keys).map do |result|
28
+ load result, options
29
+ end
30
+ end
31
+
32
+ private
33
+ def dump(val, options)
34
+ yield dump?(options) ? _dump(val) : val
35
+ end
36
+
37
+ def load(val, options)
38
+ load?(val, options) ? _load(val) : val
39
+ end
40
+
41
+ def dump?(options)
42
+ !(options && options[:raw])
43
+ end
44
+
45
+ def load?(result, options)
46
+ result && result.size > 0 && dump?(options)
47
+ end
48
+
49
+ if defined?(Encoding)
50
+ def encode(string)
51
+ string.to_s.force_encoding(Encoding::BINARY)
52
+ end
53
+ else
54
+ def encode(string)
55
+ string
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,49 @@
1
+ require 'json'
2
+
3
+ class Redis
4
+ class Store < self
5
+ module Strategy
6
+ module Json
7
+ private
8
+ SERIALIZABLE = [String, TrueClass, FalseClass, NilClass, Numeric, Date, Time].freeze
9
+ MARSHAL_INDICATORS = ["\x04", "\004", "\u0004"].freeze
10
+
11
+ def _dump(object)
12
+ object = _marshal(object)
13
+ object.to_json
14
+ end
15
+
16
+ def _load(string)
17
+ object = JSON.parse(string, :symbolize_names => true)
18
+ _unmarshal(object)
19
+ end
20
+
21
+ def _marshal(object)
22
+ case object
23
+ when Hash
24
+ object.each { |k,v| object[k] = _marshal(v) }
25
+ when Array
26
+ object.each_with_index { |v, i| object[i] = _marshal(v) }
27
+ when *SERIALIZABLE
28
+ object
29
+ else
30
+ ::Marshal.dump(object)
31
+ end
32
+ end
33
+
34
+ def _unmarshal(object)
35
+ case object
36
+ when Hash
37
+ object.each { |k,v| object[k] = _unmarshal(v) }
38
+ when Array
39
+ object.each_with_index { |v, i| object[i] = _unmarshal(v) }
40
+ when String
41
+ MARSHAL_INDICATORS.any?{ |indicator| object.start_with?(indicator) } ? ::Marshal.load(object) : object
42
+ else
43
+ object
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,67 @@
1
+ class Redis
2
+ class Store < self
3
+ module Strategy
4
+ module JsonSession
5
+
6
+ class Error < StandardError
7
+ end
8
+
9
+ class SerializationError < Redis::Store::Strategy::JsonSession::Error
10
+ def initialize(object)
11
+ super "Cannot correctly serialize object: #{object.inspect}"
12
+ end
13
+ end
14
+
15
+ private
16
+ SERIALIZABLE = [String, TrueClass, FalseClass, NilClass, Numeric, Date, Time, Symbol]
17
+ MARSHAL_INDICATORS = ["\x04", "\004", "\u0004"]
18
+
19
+ def _dump(object)
20
+ object = _marshal(object)
21
+ JSON.generate(object)
22
+ end
23
+
24
+ def _load(string)
25
+ object =
26
+ string.start_with?(*MARSHAL_INDICATORS) ? ::Marshal.load(string) : JSON.parse(string)
27
+ _unmarshal(object)
28
+ end
29
+
30
+ def _marshal(object)
31
+ case object
32
+ when Hash
33
+ marshal_hash(object)
34
+ when Array
35
+ object.each_with_index { |v, i| object[i] = _marshal(v) }
36
+ when Set
37
+ _marshal(object.to_a)
38
+ when String
39
+ object.encoding == Encoding::ASCII_8BIT ? object.to_json_raw_object : object
40
+ when *SERIALIZABLE
41
+ object
42
+ else
43
+ raise SerializationError.new(object)
44
+ end
45
+ end
46
+
47
+ def marshal_hash(object)
48
+ object.each { |k,v| object[k] = _marshal(v) }
49
+ end
50
+
51
+ def _unmarshal(object)
52
+ case object
53
+ when Hash
54
+ object.each { |k,v| object[k] = _unmarshal(v) }
55
+ when Array
56
+ object.each_with_index { |v, i| object[i] = _unmarshal(v) }
57
+ when String
58
+ object.start_with?(*MARSHAL_INDICATORS) ? ::Marshal.load(object) : object
59
+ else
60
+ object
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end