instructure-redis-store 1.0.0.1.instructure1
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.
- data/.travis.yml +7 -0
 - data/CHANGELOG +311 -0
 - data/Gemfile +34 -0
 - data/MIT-LICENSE +20 -0
 - data/README.md +239 -0
 - data/Rakefile +60 -0
 - data/VERSION +1 -0
 - data/lib/action_controller/session/redis_session_store.rb +81 -0
 - data/lib/active_support/cache/redis_store.rb +254 -0
 - data/lib/cache/merb/redis_store.rb +79 -0
 - data/lib/cache/sinatra/redis_store.rb +131 -0
 - data/lib/i18n/backend/redis.rb +67 -0
 - data/lib/rack/cache/redis_entitystore.rb +48 -0
 - data/lib/rack/cache/redis_metastore.rb +40 -0
 - data/lib/rack/session/merb.rb +32 -0
 - data/lib/rack/session/redis.rb +88 -0
 - data/lib/redis-store.rb +45 -0
 - data/lib/redis/distributed_store.rb +39 -0
 - data/lib/redis/factory.rb +46 -0
 - data/lib/redis/store.rb +39 -0
 - data/lib/redis/store/interface.rb +17 -0
 - data/lib/redis/store/marshalling.rb +51 -0
 - data/lib/redis/store/namespace.rb +62 -0
 - data/lib/redis/store/ttl.rb +37 -0
 - data/lib/redis/store/version.rb +12 -0
 - data/spec/action_controller/session/redis_session_store_spec.rb +126 -0
 - data/spec/active_support/cache/redis_store_spec.rb +426 -0
 - data/spec/cache/merb/redis_store_spec.rb +143 -0
 - data/spec/cache/sinatra/redis_store_spec.rb +192 -0
 - data/spec/config/node-one.conf +417 -0
 - data/spec/config/node-two.conf +417 -0
 - data/spec/config/redis.conf +417 -0
 - data/spec/i18n/backend/redis_spec.rb +72 -0
 - data/spec/rack/cache/entitystore/pony.jpg +0 -0
 - data/spec/rack/cache/entitystore/redis_spec.rb +124 -0
 - data/spec/rack/cache/metastore/redis_spec.rb +259 -0
 - data/spec/rack/session/redis_spec.rb +234 -0
 - data/spec/redis/distributed_store_spec.rb +55 -0
 - data/spec/redis/factory_spec.rb +110 -0
 - data/spec/redis/store/interface_spec.rb +23 -0
 - data/spec/redis/store/marshalling_spec.rb +119 -0
 - data/spec/redis/store/namespace_spec.rb +76 -0
 - data/spec/redis/store/version_spec.rb +7 -0
 - data/spec/redis/store_spec.rb +13 -0
 - data/spec/spec_helper.rb +43 -0
 - data/tasks/redis.tasks.rb +235 -0
 - metadata +249 -0
 
| 
         @@ -0,0 +1,131 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sinatra
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Cache
         
     | 
| 
      
 3 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def register(app)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    app.set :cache, RedisStore.new
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
                  alias_method :registered, :register
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                class RedisStore
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Instantiate the store.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # Example:
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   RedisStore.new
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #     # => host: localhost,   port: 6379,  db: 0
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   RedisStore.new "example.com"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #     # => host: example.com, port: 6379,  db: 0
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   RedisStore.new "example.com:23682"
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #     # => host: example.com, port: 23682, db: 0
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #   RedisStore.new "example.com:23682/1"
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #     # => host: example.com, port: 23682, db: 1
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #   RedisStore.new "example.com:23682/1/theplaylist"
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #     # => host: example.com, port: 23682, db: 1, namespace: theplaylist
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #
         
     | 
| 
      
 29 
     | 
    
         
            +
                  #   RedisStore.new "localhost:6379/0", "localhost:6380/0"
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #     # => instantiate a cluster
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def initialize(*addresses)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @data = Redis::Factory.create addresses
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def write(key, value, options = nil)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    if options && options[:unless_exist]
         
     | 
| 
      
 37 
     | 
    
         
            +
                      @data.setnx key, value, options
         
     | 
| 
      
 38 
     | 
    
         
            +
                    else
         
     | 
| 
      
 39 
     | 
    
         
            +
                      @data.set key, value, options
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def read(key, options = nil)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @data.get(key, options)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def delete(key, options = nil)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @data.del key
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def exist?(key, options = nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    @data.exists key
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  # Increment a key in the store.
         
     | 
| 
      
 56 
     | 
    
         
            +
                  #
         
     | 
| 
      
 57 
     | 
    
         
            +
                  # If the key doesn't exist it will be initialized on 0.
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # If the key exist but it isn't a Fixnum it will be initialized on 0.
         
     | 
| 
      
 59 
     | 
    
         
            +
                  #
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # Example:
         
     | 
| 
      
 61 
     | 
    
         
            +
                  #   We have two objects in cache:
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #     counter # => 23
         
     | 
| 
      
 63 
     | 
    
         
            +
                  #     rabbit  # => #<Rabbit:0x5eee6c>
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #   cache.increment "counter"
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #   cache.read "counter", :raw => true      # => "24"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  #
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #   cache.increment "counter", 6
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #   cache.read "counter", :raw => true      # => "30"
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #
         
     | 
| 
      
 71 
     | 
    
         
            +
                  #   cache.increment "a counter"
         
     | 
| 
      
 72 
     | 
    
         
            +
                  #   cache.read "a counter", :raw => true    # => "1"
         
     | 
| 
      
 73 
     | 
    
         
            +
                  #
         
     | 
| 
      
 74 
     | 
    
         
            +
                  #   cache.increment "rabbit"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  #   cache.read "rabbit", :raw => true       # => "1"
         
     | 
| 
      
 76 
     | 
    
         
            +
                  def increment(key, amount = 1)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    @data.incrby key, amount
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  # Decrement a key in the store
         
     | 
| 
      
 81 
     | 
    
         
            +
                  #
         
     | 
| 
      
 82 
     | 
    
         
            +
                  # If the key doesn't exist it will be initialized on 0.
         
     | 
| 
      
 83 
     | 
    
         
            +
                  # If the key exist but it isn't a Fixnum it will be initialized on 0.
         
     | 
| 
      
 84 
     | 
    
         
            +
                  #
         
     | 
| 
      
 85 
     | 
    
         
            +
                  # Example:
         
     | 
| 
      
 86 
     | 
    
         
            +
                  #   We have two objects in cache:
         
     | 
| 
      
 87 
     | 
    
         
            +
                  #     counter # => 23
         
     | 
| 
      
 88 
     | 
    
         
            +
                  #     rabbit  # => #<Rabbit:0x5eee6c>
         
     | 
| 
      
 89 
     | 
    
         
            +
                  #
         
     | 
| 
      
 90 
     | 
    
         
            +
                  #   cache.decrement "counter"
         
     | 
| 
      
 91 
     | 
    
         
            +
                  #   cache.read "counter", :raw => true      # => "22"
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #
         
     | 
| 
      
 93 
     | 
    
         
            +
                  #   cache.decrement "counter", 2
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #   cache.read "counter", :raw => true      # => "20"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  #
         
     | 
| 
      
 96 
     | 
    
         
            +
                  #   cache.decrement "a counter"
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #   cache.read "a counter", :raw => true    # => "-1"
         
     | 
| 
      
 98 
     | 
    
         
            +
                  #
         
     | 
| 
      
 99 
     | 
    
         
            +
                  #   cache.decrement "rabbit"
         
     | 
| 
      
 100 
     | 
    
         
            +
                  #   cache.read "rabbit", :raw => true       # => "-1"
         
     | 
| 
      
 101 
     | 
    
         
            +
                  def decrement(key, amount = 1)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    @data.decrby key, amount
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  # Delete objects for matched keys.
         
     | 
| 
      
 106 
     | 
    
         
            +
                  #
         
     | 
| 
      
 107 
     | 
    
         
            +
                  # Example:
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #   cache.del_matched "rab*"
         
     | 
| 
      
 109 
     | 
    
         
            +
                  def delete_matched(matcher, options = nil)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    @data.keys(matcher).each { |key| @data.del key }
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  def fetch(key, options = {})
         
     | 
| 
      
 114 
     | 
    
         
            +
                    (!options[:force] && data = read(key, options)) || block_given? && begin
         
     | 
| 
      
 115 
     | 
    
         
            +
                      data = yield
         
     | 
| 
      
 116 
     | 
    
         
            +
                      write(key, data, options)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
                    data || nil
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  # Clear all the data from the store.
         
     | 
| 
      
 122 
     | 
    
         
            +
                  def clear
         
     | 
| 
      
 123 
     | 
    
         
            +
                    @data.flushdb
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def stats
         
     | 
| 
      
 127 
     | 
    
         
            +
                    @data.info
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
              end
         
     | 
| 
      
 131 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module I18n
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Backend
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Redis
         
     | 
| 
      
 4 
     | 
    
         
            +
                  include Base, Flatten
         
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_accessor :store
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  # Instantiate the store.
         
     | 
| 
      
 8 
     | 
    
         
            +
                  #
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # Example:
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #   RedisStore.new
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #     # => host: localhost,   port: 6379,  db: 0
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   RedisStore.new "example.com"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #     # => host: example.com, port: 6379,  db: 0
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   RedisStore.new "example.com:23682"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #     # => host: example.com, port: 23682, db: 0
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #   RedisStore.new "example.com:23682/1"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #     # => host: example.com, port: 23682, db: 1
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   RedisStore.new "example.com:23682/1/theplaylist"
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #     # => host: example.com, port: 23682, db: 1, namespace: theplaylist
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #   RedisStore.new "localhost:6379/0", "localhost:6380/0"
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #     # => instantiate a cluster
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def initialize(*addresses)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @store = ::Redis::Factory.create(addresses)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def translate(locale, key, options = {})
         
     | 
| 
      
 32 
     | 
    
         
            +
                    options[:resolve] ||= false
         
     | 
| 
      
 33 
     | 
    
         
            +
                    super locale, key, options
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def store_translations(locale, data, options = {})
         
     | 
| 
      
 37 
     | 
    
         
            +
                    escape = options.fetch(:escape, true)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    flatten_translations(locale, data, escape, false).each do |key, value|
         
     | 
| 
      
 39 
     | 
    
         
            +
                      case value
         
     | 
| 
      
 40 
     | 
    
         
            +
                      when Proc
         
     | 
| 
      
 41 
     | 
    
         
            +
                        raise "Key-value stores cannot handle procs"
         
     | 
| 
      
 42 
     | 
    
         
            +
                      else
         
     | 
| 
      
 43 
     | 
    
         
            +
                        @store.set "#{locale}.#{key}", value
         
     | 
| 
      
 44 
     | 
    
         
            +
                      end
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def available_locales
         
     | 
| 
      
 49 
     | 
    
         
            +
                    locales = @store.keys.map { |k| k =~ /\./; $` }
         
     | 
| 
      
 50 
     | 
    
         
            +
                    locales.uniq!
         
     | 
| 
      
 51 
     | 
    
         
            +
                    locales.compact!
         
     | 
| 
      
 52 
     | 
    
         
            +
                    locales.map! { |k| k.to_sym }
         
     | 
| 
      
 53 
     | 
    
         
            +
                    locales
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 57 
     | 
    
         
            +
                    def lookup(locale, key, scope = [], options = {})
         
     | 
| 
      
 58 
     | 
    
         
            +
                      key = normalize_flat_keys(locale, key, scope, options[:separator])
         
     | 
| 
      
 59 
     | 
    
         
            +
                      @store.get "#{locale}.#{key}"
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    def resolve_link(locale, key)
         
     | 
| 
      
 63 
     | 
    
         
            +
                      key
         
     | 
| 
      
 64 
     | 
    
         
            +
                    end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Cache
         
     | 
| 
      
 3 
     | 
    
         
            +
                class EntityStore
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class RedisBase < EntityStore
         
     | 
| 
      
 5 
     | 
    
         
            +
                    # The underlying ::Redis instance used to communicate with the Redis daemon.
         
     | 
| 
      
 6 
     | 
    
         
            +
                    attr_reader :cache
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    extend Rack::Utils
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def open(key)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      data = read(key)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      data && [data]
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    def self.resolve(uri)
         
     | 
| 
      
 16 
     | 
    
         
            +
                      new ::Redis::Factory.convert_to_redis_client_options(uri.to_s)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  class Redis < RedisBase
         
     | 
| 
      
 21 
     | 
    
         
            +
                    def initialize(server, options = {})
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @cache = ::Redis.new server
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    def exist?(key)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      cache.exists key
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    def read(key)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      cache.get key
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    def write(body)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      buf = StringIO.new
         
     | 
| 
      
 35 
     | 
    
         
            +
                      key, size = slurp(body){|part| buf.write(part) }
         
     | 
| 
      
 36 
     | 
    
         
            +
                      [key, size] if cache.set(key, buf.string)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    def purge(key)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      cache.del key
         
     | 
| 
      
 41 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  REDIS = Redis
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Cache
         
     | 
| 
      
 3 
     | 
    
         
            +
                class MetaStore
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class RedisBase < MetaStore
         
     | 
| 
      
 5 
     | 
    
         
            +
                    extend Rack::Utils
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                    # The Redis::Store object used to communicate with the Redis daemon.
         
     | 
| 
      
 8 
     | 
    
         
            +
                    attr_reader :cache
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def self.resolve(uri)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      new ::Redis::Factory.convert_to_redis_client_options(uri.to_s)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  class Redis < RedisBase
         
     | 
| 
      
 16 
     | 
    
         
            +
                    def initialize(server, options = {})
         
     | 
| 
      
 17 
     | 
    
         
            +
                      options[:redis_server] ||= server
         
     | 
| 
      
 18 
     | 
    
         
            +
                      @cache = ::Redis::Factory.create options
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    def read(key)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      key = hexdigest(key)
         
     | 
| 
      
 23 
     | 
    
         
            +
                      cache.get(key) || []
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    def write(key, entries)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      key = hexdigest(key)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      cache.set(key, entries)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    def purge(key)
         
     | 
| 
      
 32 
     | 
    
         
            +
                      cache.del(hexdigest(key))
         
     | 
| 
      
 33 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  REDIS = Redis
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Merb
         
     | 
| 
      
 2 
     | 
    
         
            +
              # HACK for cyclic dependency: redis-store is required before Merb session stores
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Mash < Hash; end
         
     | 
| 
      
 4 
     | 
    
         
            +
              class SessionContainer < Mash; class_inheritable_accessor :session_store_type end
         
     | 
| 
      
 5 
     | 
    
         
            +
              class SessionStoreContainer < SessionContainer; end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              class RedisSession < SessionStoreContainer
         
     | 
| 
      
 8 
     | 
    
         
            +
                self.session_store_type = :redis
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              module RedisStore
         
     | 
| 
      
 12 
     | 
    
         
            +
                def retrieve_session(session_id)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  get("session:#{session_id}")
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def store_session(session_id, data)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  set("session:#{session_id}", data)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def delete_session(session_id)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  delete("session:#{session_id}")
         
     | 
| 
      
 22 
     | 
    
         
            +
                end    
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 27 
     | 
    
         
            +
              module Session
         
     | 
| 
      
 28 
     | 
    
         
            +
                class Redis
         
     | 
| 
      
 29 
     | 
    
         
            +
                  include Merb::RedisStore
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,88 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Session
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Redis < Abstract::ID
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_reader :mutex, :pool
         
     | 
| 
      
 5 
     | 
    
         
            +
                  DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :redis_server => "redis://127.0.0.1:6379/0"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(app, options = {})
         
     | 
| 
      
 8 
     | 
    
         
            +
                    super
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @mutex = Mutex.new
         
     | 
| 
      
 10 
     | 
    
         
            +
                    options[:redis_server] ||= @default_options[:redis_server]
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @pool = ::Redis::Factory.create options
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def generate_sid
         
     | 
| 
      
 15 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 16 
     | 
    
         
            +
                      sid = super
         
     | 
| 
      
 17 
     | 
    
         
            +
                      break sid unless @pool.get(sid)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def get_session(env, sid)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    session = @pool.get(sid) if sid
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @mutex.lock if env['rack.multithread']
         
     | 
| 
      
 24 
     | 
    
         
            +
                    unless sid and session
         
     | 
| 
      
 25 
     | 
    
         
            +
                      env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
         
     | 
| 
      
 26 
     | 
    
         
            +
                      session = {}
         
     | 
| 
      
 27 
     | 
    
         
            +
                      sid = generate_sid
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ret = @pool.set sid, session
         
     | 
| 
      
 29 
     | 
    
         
            +
                      raise "Session collision on '#{sid.inspect}'" unless ret
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    session.instance_variable_set('@old', {}.merge(session))
         
     | 
| 
      
 32 
     | 
    
         
            +
                    return [sid, session]
         
     | 
| 
      
 33 
     | 
    
         
            +
                  rescue Errno::ECONNREFUSED
         
     | 
| 
      
 34 
     | 
    
         
            +
                    warn "#{self} is unable to find server."
         
     | 
| 
      
 35 
     | 
    
         
            +
                    warn $!.inspect
         
     | 
| 
      
 36 
     | 
    
         
            +
                    return [ nil, {} ]
         
     | 
| 
      
 37 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @mutex.unlock if env['rack.multithread']
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def set_session(env, session_id, new_session, options)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @mutex.lock if env['rack.multithread']
         
     | 
| 
      
 43 
     | 
    
         
            +
                    session = @pool.get(session_id) rescue {}
         
     | 
| 
      
 44 
     | 
    
         
            +
                    if options[:renew] or options[:drop]
         
     | 
| 
      
 45 
     | 
    
         
            +
                      @pool.del session_id
         
     | 
| 
      
 46 
     | 
    
         
            +
                      return false if options[:drop]
         
     | 
| 
      
 47 
     | 
    
         
            +
                      session_id = generate_sid
         
     | 
| 
      
 48 
     | 
    
         
            +
                      @pool.set session_id, 0
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                    old_session = new_session.instance_variable_get('@old') || {}
         
     | 
| 
      
 51 
     | 
    
         
            +
                    session = merge_sessions session_id, old_session, new_session, session
         
     | 
| 
      
 52 
     | 
    
         
            +
                    @pool.set session_id, session, options
         
     | 
| 
      
 53 
     | 
    
         
            +
                    return session_id
         
     | 
| 
      
 54 
     | 
    
         
            +
                  rescue Errno::ECONNREFUSED
         
     | 
| 
      
 55 
     | 
    
         
            +
                    warn "#{self} is unable to find server."
         
     | 
| 
      
 56 
     | 
    
         
            +
                    warn $!.inspect
         
     | 
| 
      
 57 
     | 
    
         
            +
                    return false
         
     | 
| 
      
 58 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @mutex.unlock if env['rack.multithread']
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  def destroy_session(env, session_id, options)
         
     | 
| 
      
 63 
     | 
    
         
            +
                    options = { :renew => true }.update(options) unless options[:drop]
         
     | 
| 
      
 64 
     | 
    
         
            +
                    set_session(env, session_id, 0, options)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  private
         
     | 
| 
      
 68 
     | 
    
         
            +
                    def merge_sessions(sid, old, new, cur=nil)
         
     | 
| 
      
 69 
     | 
    
         
            +
                      cur ||= {}
         
     | 
| 
      
 70 
     | 
    
         
            +
                      unless Hash === old and Hash === new
         
     | 
| 
      
 71 
     | 
    
         
            +
                        warn 'Bad old or new sessions provided.'
         
     | 
| 
      
 72 
     | 
    
         
            +
                        return cur
         
     | 
| 
      
 73 
     | 
    
         
            +
                      end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                      delete = old.keys - new.keys
         
     | 
| 
      
 76 
     | 
    
         
            +
                      warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
         
     | 
| 
      
 77 
     | 
    
         
            +
                      delete.each{|k| cur.delete k }
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      update = new.keys.select{|k| new[k] != old[k] }
         
     | 
| 
      
 80 
     | 
    
         
            +
                      warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
         
     | 
| 
      
 81 
     | 
    
         
            +
                      update.each{|k| cur[k] = new[k] }
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                      cur
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
    
        data/lib/redis-store.rb
    ADDED
    
    | 
         @@ -0,0 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "redis"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "redis/distributed"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "redis/factory"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "redis/store/interface"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "redis/store/ttl"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "redis/store/namespace"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "redis/store/marshalling"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "redis/store/version"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "redis/store"
         
     | 
| 
      
 10 
     | 
    
         
            +
            require "redis/distributed_store"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            # Cache store
         
     | 
| 
      
 13 
     | 
    
         
            +
            if defined?(Sinatra)
         
     | 
| 
      
 14 
     | 
    
         
            +
              require "cache/sinatra/redis_store"
         
     | 
| 
      
 15 
     | 
    
         
            +
            elsif defined?(Merb)
         
     | 
| 
      
 16 
     | 
    
         
            +
              # HACK for cyclic dependency: redis-store is required before merb-cache
         
     | 
| 
      
 17 
     | 
    
         
            +
              module Merb; module Cache; class AbstractStore; end end end
         
     | 
| 
      
 18 
     | 
    
         
            +
              require "cache/merb/redis_store"
         
     | 
| 
      
 19 
     | 
    
         
            +
            elsif defined?(ActiveSupport)
         
     | 
| 
      
 20 
     | 
    
         
            +
              require "active_support/cache/redis_store"
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            # Rack::Session
         
     | 
| 
      
 24 
     | 
    
         
            +
            if defined?(Rack::Session)
         
     | 
| 
      
 25 
     | 
    
         
            +
              require "rack/session/abstract/id"
         
     | 
| 
      
 26 
     | 
    
         
            +
              require "rack/session/redis"
         
     | 
| 
      
 27 
     | 
    
         
            +
              if defined?(Merb)
         
     | 
| 
      
 28 
     | 
    
         
            +
                require "rack/session/merb"
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            if defined?(Rails)
         
     | 
| 
      
 33 
     | 
    
         
            +
              require "action_controller/session/redis_session_store"
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            # Rack::Cache
         
     | 
| 
      
 37 
     | 
    
         
            +
            if defined?(Rack::Cache)
         
     | 
| 
      
 38 
     | 
    
         
            +
              require "rack/cache/key"
         
     | 
| 
      
 39 
     | 
    
         
            +
              require "rack/cache/redis_metastore"
         
     | 
| 
      
 40 
     | 
    
         
            +
              require "rack/cache/redis_entitystore"
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            if defined?(I18n)
         
     | 
| 
      
 44 
     | 
    
         
            +
              require "i18n/backend/redis"
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     |