honkster-redis-store 0.3.10
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/.gitignore +11 -0
- data/Gemfile +14 -0
- data/MIT-LICENSE +20 -0
- data/README.md +105 -0
- data/Rakefile +70 -0
- data/VERSION +1 -0
- data/lib/cache/merb/redis_store.rb +63 -0
- data/lib/cache/rails/redis_session_store.rb +61 -0
- data/lib/cache/rails/redis_store.rb +109 -0
- data/lib/cache/sinatra/redis_store.rb +118 -0
- data/lib/rack/cache/redis_entitystore.rb +51 -0
- data/lib/rack/cache/redis_metastore.rb +42 -0
- data/lib/rack/session/merb.rb +32 -0
- data/lib/rack/session/redis.rb +81 -0
- data/lib/redis/distributed_marshaled_redis.rb +16 -0
- data/lib/redis/marshaled_redis.rb +52 -0
- data/lib/redis/redis_factory.rb +26 -0
- data/lib/redis-store.rb +33 -0
- data/redis-store.gemspec +80 -0
- data/spec/cache/merb/redis_store_spec.rb +140 -0
- data/spec/cache/rails/redis_session_store_spec.rb +77 -0
- data/spec/cache/rails/redis_store_spec.rb +168 -0
- data/spec/cache/sinatra/redis_store_spec.rb +189 -0
- data/spec/config/master.conf +171 -0
- data/spec/config/single.conf +171 -0
- data/spec/config/slave.conf +171 -0
- data/spec/rack/cache/entitystore/pony.jpg +0 -0
- data/spec/rack/cache/entitystore/redis_spec.rb +118 -0
- data/spec/rack/cache/metastore/redis_spec.rb +255 -0
- data/spec/rack/session/redis_spec.rb +234 -0
- data/spec/redis/distributed_marshaled_redis_spec.rb +33 -0
- data/spec/redis/marshaled_redis_spec.rb +54 -0
- data/spec/redis/redis_factory_spec.rb +68 -0
- data/spec/spec_helper.rb +24 -0
- data/tasks/redis.tasks.rb +78 -0
- metadata +106 -0
| @@ -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,81 @@ | |
| 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 => "localhost:6379"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def initialize(app, options = {})
         | 
| 8 | 
            +
                    super
         | 
| 9 | 
            +
                    @mutex = Mutex.new
         | 
| 10 | 
            +
                    @pool = RedisFactory.create options[:redis_server] || @default_options[:redis_server]
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def generate_sid
         | 
| 14 | 
            +
                    loop do
         | 
| 15 | 
            +
                      sid = super
         | 
| 16 | 
            +
                      break sid unless @pool.marshalled_get(sid)
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def get_session(env, sid)
         | 
| 21 | 
            +
                    session = @pool.marshalled_get(sid) if sid
         | 
| 22 | 
            +
                    @mutex.lock if env['rack.multithread']
         | 
| 23 | 
            +
                    unless sid and session
         | 
| 24 | 
            +
                      env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
         | 
| 25 | 
            +
                      session = {}
         | 
| 26 | 
            +
                      sid = generate_sid
         | 
| 27 | 
            +
                      ret = @pool.marshalled_set sid, session
         | 
| 28 | 
            +
                      raise "Session collision on '#{sid.inspect}'" unless ret
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                    session.instance_variable_set('@old', {}.merge(session))
         | 
| 31 | 
            +
                    return [sid, session]
         | 
| 32 | 
            +
                  rescue Errno::ECONNREFUSED
         | 
| 33 | 
            +
                    warn "#{self} is unable to find server."
         | 
| 34 | 
            +
                    warn $!.inspect
         | 
| 35 | 
            +
                    return [ nil, {} ]
         | 
| 36 | 
            +
                  ensure
         | 
| 37 | 
            +
                    @mutex.unlock if env['rack.multithread']
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def set_session(env, session_id, new_session, options)
         | 
| 41 | 
            +
                    @mutex.lock if env['rack.multithread']
         | 
| 42 | 
            +
                    session = @pool.marshalled_get(session_id) rescue {}
         | 
| 43 | 
            +
                    if options[:renew] or options[:drop]
         | 
| 44 | 
            +
                      @pool.del session_id
         | 
| 45 | 
            +
                      return false if options[:drop]
         | 
| 46 | 
            +
                      session_id = generate_sid
         | 
| 47 | 
            +
                      @pool.marshalled_set session_id, 0
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                    old_session = new_session.instance_variable_get('@old') || {}
         | 
| 50 | 
            +
                    session = merge_sessions session_id, old_session, new_session, session
         | 
| 51 | 
            +
                    @pool.marshalled_set session_id, session, options
         | 
| 52 | 
            +
                    return session_id
         | 
| 53 | 
            +
                  rescue Errno::ECONNREFUSED
         | 
| 54 | 
            +
                    warn "#{self} is unable to find server."
         | 
| 55 | 
            +
                    warn $!.inspect
         | 
| 56 | 
            +
                    return false
         | 
| 57 | 
            +
                  ensure
         | 
| 58 | 
            +
                    @mutex.unlock if env['rack.multithread']
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  private
         | 
| 62 | 
            +
                    def merge_sessions(sid, old, new, cur=nil)
         | 
| 63 | 
            +
                      cur ||= {}
         | 
| 64 | 
            +
                      unless Hash === old and Hash === new
         | 
| 65 | 
            +
                        warn 'Bad old or new sessions provided.'
         | 
| 66 | 
            +
                        return cur
         | 
| 67 | 
            +
                      end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                      delete = old.keys - new.keys
         | 
| 70 | 
            +
                      warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
         | 
| 71 | 
            +
                      delete.each{|k| cur.del k }
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                      update = new.keys.select{|k| new[k] != old[k] }
         | 
| 74 | 
            +
                      warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
         | 
| 75 | 
            +
                      update.each{|k| cur[k] = new[k] }
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                      cur
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            class DistributedMarshaledRedis < DistRedis
         | 
| 2 | 
            +
              attr_reader :ring
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              def initialize(addresses)
         | 
| 5 | 
            +
                nodes = addresses.map do |address|
         | 
| 6 | 
            +
                  MarshaledRedis.new address
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
                @ring = Redis::HashRing.new nodes
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def nodes
         | 
| 12 | 
            +
                ring.nodes
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              alias_method :flushdb, :delete_cloud!
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            class MarshaledRedis < Redis::Client
         | 
| 2 | 
            +
              def marshalled_set(key, val, options = nil)
         | 
| 3 | 
            +
                val = marshal_value(val, options)
         | 
| 4 | 
            +
                if expires_in = expires_in(options)
         | 
| 5 | 
            +
                  set_with_expire key, val, expires_in
         | 
| 6 | 
            +
                else
         | 
| 7 | 
            +
                  set key, val
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def marshalled_setnx(key, val, options = nil)
         | 
| 12 | 
            +
                val = marshal_value(val, options)
         | 
| 13 | 
            +
                if expires_in = expires_in(options)
         | 
| 14 | 
            +
                  setnx_with_expire key, val, expires_in
         | 
| 15 | 
            +
                else
         | 
| 16 | 
            +
                  setnx key, val
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def setnx_with_expire(key, value, ttl)
         | 
| 21 | 
            +
                multi do
         | 
| 22 | 
            +
                  setnx(key, val)
         | 
| 23 | 
            +
                  expire(key, expires_in)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def marshalled_get(key, options = nil)
         | 
| 28 | 
            +
                result = call_command([:get, key])
         | 
| 29 | 
            +
                result = Marshal.load result if unmarshal?(result, options)
         | 
| 30 | 
            +
                result
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              private
         | 
| 34 | 
            +
                def marshal_value(val, options)
         | 
| 35 | 
            +
                  raw?(options) ? val : Marshal.dump(val)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def unmarshal?(result, options)
         | 
| 39 | 
            +
                  result && result.size > 0 && !raw?(options)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def raw?(options)
         | 
| 43 | 
            +
                  options && options[:raw]
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def expires_in(options)
         | 
| 47 | 
            +
                  if options
         | 
| 48 | 
            +
                    # Rack::Session           Merb                    Rails/Sinatra
         | 
| 49 | 
            +
                    options[:expire_after] || options[:expires_in] || options[:expire_in]
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            class RedisFactory
         | 
| 2 | 
            +
              class << self
         | 
| 3 | 
            +
                def create(*redis_client_options)
         | 
| 4 | 
            +
                  redis_client_options = redis_client_options.flatten.compact.inject([]) do |result, address|
         | 
| 5 | 
            +
                    result << convert_to_redis_client_options(address)
         | 
| 6 | 
            +
                    result
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
                  if redis_client_options.size > 1
         | 
| 9 | 
            +
                    DistributedMarshaledRedis.new redis_client_options
         | 
| 10 | 
            +
                  else
         | 
| 11 | 
            +
                    MarshaledRedis.new redis_client_options.first || {}
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def convert_to_redis_client_options(address_or_options)
         | 
| 16 | 
            +
                  return address_or_options if address_or_options.is_a?(Hash)
         | 
| 17 | 
            +
                  host, port = address_or_options.split /\:/
         | 
| 18 | 
            +
                  port, db   = port.split /\// if port
         | 
| 19 | 
            +
                  options = {}
         | 
| 20 | 
            +
                  options[:host] = host if host
         | 
| 21 | 
            +
                  options[:port] = port if port
         | 
| 22 | 
            +
                  options[:db]  = db.to_i if db
         | 
| 23 | 
            +
                  options
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
    
        data/lib/redis-store.rb
    ADDED
    
    | @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require "redis"
         | 
| 2 | 
            +
            require "redis/dist_redis"
         | 
| 3 | 
            +
            require "redis/redis_factory"
         | 
| 4 | 
            +
            require "redis/marshaled_redis"
         | 
| 5 | 
            +
            require "redis/distributed_marshaled_redis"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            # Cache store
         | 
| 8 | 
            +
            if defined?(Sinatra)
         | 
| 9 | 
            +
              require "cache/sinatra/redis_store"
         | 
| 10 | 
            +
            elsif defined?(Merb)
         | 
| 11 | 
            +
              # HACK for cyclic dependency: redis-store is required before merb-cache
         | 
| 12 | 
            +
              module Merb; module Cache; class AbstractStore; end end end
         | 
| 13 | 
            +
              require "cache/merb/redis_store"
         | 
| 14 | 
            +
            elsif defined?(Rails)
         | 
| 15 | 
            +
              require "cache/rails/redis_store"
         | 
| 16 | 
            +
              require "cache/rails/redis_session_store"
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            # Rack::Session
         | 
| 20 | 
            +
            if defined?(Rack::Session)
         | 
| 21 | 
            +
              require "rack/session/abstract/id"
         | 
| 22 | 
            +
              require "rack/session/redis"
         | 
| 23 | 
            +
              if defined?(Merb)
         | 
| 24 | 
            +
                require "rack/session/merb"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            # Rack::Cache
         | 
| 29 | 
            +
            if defined?(Rack::Cache)
         | 
| 30 | 
            +
              require "rack/cache/key"
         | 
| 31 | 
            +
              require "rack/cache/redis_metastore"
         | 
| 32 | 
            +
              require "rack/cache/redis_entitystore"
         | 
| 33 | 
            +
            end
         | 
    
        data/redis-store.gemspec
    ADDED
    
    | @@ -0,0 +1,80 @@ | |
| 1 | 
            +
            # Generated by jeweler
         | 
| 2 | 
            +
            # DO NOT EDIT THIS FILE
         | 
| 3 | 
            +
            # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
         | 
| 4 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |s|
         | 
| 7 | 
            +
              s.name = %q{redis-store}
         | 
| 8 | 
            +
              s.version = "0.3.7"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 | 
            +
              s.authors = ["Luca Guidi"]
         | 
| 12 | 
            +
              s.date = %q{2009-11-15}
         | 
| 13 | 
            +
              s.description = %q{Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks.}
         | 
| 14 | 
            +
              s.email = %q{guidi.luca@gmail.com}
         | 
| 15 | 
            +
              s.extra_rdoc_files = [
         | 
| 16 | 
            +
                "README.md"
         | 
| 17 | 
            +
              ]
         | 
| 18 | 
            +
              s.files = [
         | 
| 19 | 
            +
                ".gitignore",
         | 
| 20 | 
            +
                 "Gemfile",
         | 
| 21 | 
            +
                 "MIT-LICENSE",
         | 
| 22 | 
            +
                 "README.md",
         | 
| 23 | 
            +
                 "Rakefile",
         | 
| 24 | 
            +
                 "VERSION",
         | 
| 25 | 
            +
                 "lib/cache/merb/redis_store.rb",
         | 
| 26 | 
            +
                 "lib/cache/rails/redis_store.rb",
         | 
| 27 | 
            +
                 "lib/cache/sinatra/redis_store.rb",
         | 
| 28 | 
            +
                 "lib/rack/cache/redis_entitystore.rb",
         | 
| 29 | 
            +
                 "lib/rack/cache/redis_metastore.rb",
         | 
| 30 | 
            +
                 "lib/rack/session/merb.rb",
         | 
| 31 | 
            +
                 "lib/rack/session/redis.rb",
         | 
| 32 | 
            +
                 "lib/redis-store.rb",
         | 
| 33 | 
            +
                 "lib/redis/distributed_marshaled_redis.rb",
         | 
| 34 | 
            +
                 "lib/redis/marshaled_redis.rb",
         | 
| 35 | 
            +
                 "lib/redis/redis_factory.rb",
         | 
| 36 | 
            +
                 "redis-store.gemspec",
         | 
| 37 | 
            +
                 "spec/cache/merb/redis_store_spec.rb",
         | 
| 38 | 
            +
                 "spec/cache/rails/redis_store_spec.rb",
         | 
| 39 | 
            +
                 "spec/cache/sinatra/redis_store_spec.rb",
         | 
| 40 | 
            +
                 "spec/config/master.conf",
         | 
| 41 | 
            +
                 "spec/config/single.conf",
         | 
| 42 | 
            +
                 "spec/config/slave.conf",
         | 
| 43 | 
            +
                 "spec/rack/cache/entitystore/pony.jpg",
         | 
| 44 | 
            +
                 "spec/rack/cache/entitystore/redis_spec.rb",
         | 
| 45 | 
            +
                 "spec/rack/cache/metastore/redis_spec.rb",
         | 
| 46 | 
            +
                 "spec/rack/session/redis_spec.rb",
         | 
| 47 | 
            +
                 "spec/redis/distributed_marshaled_redis_spec.rb",
         | 
| 48 | 
            +
                 "spec/redis/marshaled_redis_spec.rb",
         | 
| 49 | 
            +
                 "spec/redis/redis_factory_spec.rb",
         | 
| 50 | 
            +
                 "spec/spec_helper.rb",
         | 
| 51 | 
            +
                 "tasks/redis.tasks.rb"
         | 
| 52 | 
            +
              ]
         | 
| 53 | 
            +
              s.homepage = %q{http://github.com/jodosha/redis-store}
         | 
| 54 | 
            +
              s.rdoc_options = ["--charset=UTF-8"]
         | 
| 55 | 
            +
              s.require_paths = ["lib"]
         | 
| 56 | 
            +
              s.rubygems_version = %q{1.3.5}
         | 
| 57 | 
            +
              s.summary = %q{Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks.}
         | 
| 58 | 
            +
              s.test_files = [
         | 
| 59 | 
            +
                "spec/cache/merb/redis_store_spec.rb",
         | 
| 60 | 
            +
                 "spec/cache/rails/redis_store_spec.rb",
         | 
| 61 | 
            +
                 "spec/cache/sinatra/redis_store_spec.rb",
         | 
| 62 | 
            +
                 "spec/rack/cache/entitystore/redis_spec.rb",
         | 
| 63 | 
            +
                 "spec/rack/cache/metastore/redis_spec.rb",
         | 
| 64 | 
            +
                 "spec/rack/session/redis_spec.rb",
         | 
| 65 | 
            +
                 "spec/redis/distributed_marshaled_redis_spec.rb",
         | 
| 66 | 
            +
                 "spec/redis/marshaled_redis_spec.rb",
         | 
| 67 | 
            +
                 "spec/redis/redis_factory_spec.rb",
         | 
| 68 | 
            +
                 "spec/spec_helper.rb"
         | 
| 69 | 
            +
              ]
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              if s.respond_to? :specification_version then
         | 
| 72 | 
            +
                current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
         | 
| 73 | 
            +
                s.specification_version = 3
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
         | 
| 76 | 
            +
                else
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              else
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
            end
         | 
| @@ -0,0 +1,140 @@ | |
| 1 | 
            +
            require File.join(File.dirname(__FILE__), "/../../spec_helper")
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Merb
         | 
| 4 | 
            +
              module Cache
         | 
| 5 | 
            +
                describe "Merb::Cache::RedisStore" do
         | 
| 6 | 
            +
                  before(:each) do
         | 
| 7 | 
            +
                    @store  = Merb::Cache::RedisStore.new
         | 
| 8 | 
            +
                    @dstore = Merb::Cache::RedisStore.new :servers => ["localhost:6380/1", "localhost:6381/1"]
         | 
| 9 | 
            +
                    @rabbit = OpenStruct.new :name => "bunny"
         | 
| 10 | 
            +
                    @white_rabbit = OpenStruct.new :color => "white"
         | 
| 11 | 
            +
                    with_store_management do |store|
         | 
| 12 | 
            +
                      store.write "rabbit", @rabbit
         | 
| 13 | 
            +
                      store.delete "rub-a-dub"
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  it "should accept connection params" do
         | 
| 18 | 
            +
                    redis = instantiate_store
         | 
| 19 | 
            +
                    redis.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    redis = instantiate_store "localhost"
         | 
| 22 | 
            +
                    redis.to_s.should == "Redis Client connected to localhost:6379 against DB 0"
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    redis = instantiate_store "localhost:6380"
         | 
| 25 | 
            +
                    redis.to_s.should == "Redis Client connected to localhost:6380 against DB 0"
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    redis = instantiate_store "localhost:6380/13"
         | 
| 28 | 
            +
                    redis.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  it "should instantiate a ring" do
         | 
| 32 | 
            +
                    store = instantiate_store
         | 
| 33 | 
            +
                    store.should be_kind_of(MarshaledRedis)
         | 
| 34 | 
            +
                    store = instantiate_store ["localhost:6379/0", "localhost:6379/1"]
         | 
| 35 | 
            +
                    store.should be_kind_of(DistributedMarshaledRedis)
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  it "should verify if writable" do
         | 
| 39 | 
            +
                    with_store_management do |store|
         | 
| 40 | 
            +
                      store.writable?("rabbit").should be_true
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  it "should read the data" do
         | 
| 45 | 
            +
                    with_store_management do |store|
         | 
| 46 | 
            +
                      store.read("rabbit").should === @rabbit
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  it "should read raw data" do
         | 
| 51 | 
            +
                    with_store_management do |store|
         | 
| 52 | 
            +
                      store.read("rabbit", {}, :raw => true).should == "\004\bU:\017OpenStruct{\006:\tname\"\nbunny"
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  it "should write the data" do
         | 
| 57 | 
            +
                    with_store_management do |store|
         | 
| 58 | 
            +
                      store.write "rabbit", @white_rabbit
         | 
| 59 | 
            +
                      store.read("rabbit").should === @white_rabbit
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  it "should write raw data" do
         | 
| 64 | 
            +
                    with_store_management do |store|
         | 
| 65 | 
            +
                      store.write "rabbit", @white_rabbit, {}, :raw => true
         | 
| 66 | 
            +
                      store.read("rabbit", {}, :raw => true).should == %(#<OpenStruct color="white">)
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  it "should write the data with expiration time" do
         | 
| 71 | 
            +
                    with_store_management do |store|
         | 
| 72 | 
            +
                      store.write "rabbit", @white_rabbit, {}, :expires_in => 1.second
         | 
| 73 | 
            +
                      store.read("rabbit").should === @white_rabbit ; sleep 2
         | 
| 74 | 
            +
                      store.read("rabbit").should be_nil
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  it "should not write data if :unless_exist option is true" do
         | 
| 79 | 
            +
                    with_store_management do |store|
         | 
| 80 | 
            +
                      store.write "rabbit", @white_rabbit, {}, :unless_exist => true
         | 
| 81 | 
            +
                      store.read("rabbit").should === @rabbit
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  it "should write all the data" do
         | 
| 86 | 
            +
                    with_store_management do |store|
         | 
| 87 | 
            +
                      store.write_all "rabbit", @white_rabbit
         | 
| 88 | 
            +
                      store.read("rabbit").should === @white_rabbit
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  it "should fetch data" do
         | 
| 93 | 
            +
                    with_store_management do |store|
         | 
| 94 | 
            +
                      store.fetch("rabbit").should == @rabbit
         | 
| 95 | 
            +
                      store.fetch("rub-a-dub").should be_nil
         | 
| 96 | 
            +
                      store.fetch("rub-a-dub") { "Flora de Cana" }
         | 
| 97 | 
            +
                      store.fetch("rub-a-dub").should === "Flora de Cana"
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  it "should verify existence" do
         | 
| 102 | 
            +
                    with_store_management do |store|
         | 
| 103 | 
            +
                      store.exists?("rabbit").should be_true
         | 
| 104 | 
            +
                      store.exists?("rab-a-dub").should be_false
         | 
| 105 | 
            +
                    end
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  it "should delete data" do
         | 
| 109 | 
            +
                    with_store_management do |store|
         | 
| 110 | 
            +
                      store.delete "rabbit"
         | 
| 111 | 
            +
                      store.read("rabbit").should be_nil
         | 
| 112 | 
            +
                    end
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  it "should delete all the data" do
         | 
| 116 | 
            +
                    with_store_management do |store|
         | 
| 117 | 
            +
                      store.delete_all
         | 
| 118 | 
            +
                      store.instance_variable_get(:@data).keys("*").flatten.should be_empty
         | 
| 119 | 
            +
                    end
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                  it "should delete all the data with bang method" do
         | 
| 123 | 
            +
                    with_store_management do |store|
         | 
| 124 | 
            +
                      store.delete_all!
         | 
| 125 | 
            +
                      store.instance_variable_get(:@data).keys("*").flatten.should be_empty
         | 
| 126 | 
            +
                    end
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                  private
         | 
| 130 | 
            +
                    def instantiate_store(addresses = nil)
         | 
| 131 | 
            +
                      Merb::Cache::RedisStore.new(:servers => [addresses].flatten).instance_variable_get(:@data)
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                    def with_store_management
         | 
| 135 | 
            +
                      yield @store
         | 
| 136 | 
            +
                      yield @dstore
         | 
| 137 | 
            +
                    end
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
              end
         | 
| 140 | 
            +
            end
         | 
| @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            require File.join(File.dirname(__FILE__), "/../../spec_helper")
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ActionController
         | 
| 4 | 
            +
              module Session
         | 
| 5 | 
            +
                describe "ActionController::Session::RedisSessionStore" do
         | 
| 6 | 
            +
                  attr_reader :app
         | 
| 7 | 
            +
                  before(:each) do
         | 
| 8 | 
            +
                    @app = Object.new
         | 
| 9 | 
            +
                    @store  = ActionController::Session::RedisSessionStore.new(app)
         | 
| 10 | 
            +
                    @dstore = ActionController::Session::RedisSessionStore.new app, :servers => ["localhost:6380/1", "localhost:6381/1"]
         | 
| 11 | 
            +
                    @rabbit = OpenStruct.new :name => "bunny"
         | 
| 12 | 
            +
                    @white_rabbit = OpenStruct.new :color => "white"
         | 
| 13 | 
            +
                    with_store_management do |store|
         | 
| 14 | 
            +
                      class << store
         | 
| 15 | 
            +
                        attr_reader :pool
         | 
| 16 | 
            +
                        public :get_session, :set_session
         | 
| 17 | 
            +
                      end
         | 
| 18 | 
            +
                      store.set_session({'rack.session.options' => {}}, "rabbit", @rabbit)
         | 
| 19 | 
            +
                      store.pool.del "counter"
         | 
| 20 | 
            +
                      store.pool.del "rub-a-dub"
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  it "should accept connection params" do
         | 
| 25 | 
            +
                    redis = instantiate_store
         | 
| 26 | 
            +
                    redis.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    redis = instantiate_store :servers => "localhost"
         | 
| 29 | 
            +
                    redis.to_s.should == "Redis Client connected to localhost:6379 against DB 0"
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    redis = instantiate_store :servers => "localhost:6380"
         | 
| 32 | 
            +
                    redis.to_s.should == "Redis Client connected to localhost:6380 against DB 0"
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    redis = instantiate_store :servers => "localhost:6380/13"
         | 
| 35 | 
            +
                    redis.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  it "should instantiate a ring" do
         | 
| 39 | 
            +
                    store = instantiate_store
         | 
| 40 | 
            +
                    store.should be_kind_of(MarshaledRedis)
         | 
| 41 | 
            +
                    store = instantiate_store :servers => ["localhost:6379/0", "localhost:6379/1"]
         | 
| 42 | 
            +
                    store.should be_kind_of(DistributedMarshaledRedis)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  it "should read the data" do
         | 
| 46 | 
            +
                    with_store_management do |store|
         | 
| 47 | 
            +
                      store.get_session({}, "rabbit").should === ["rabbit", @rabbit]
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  it "should write the data" do
         | 
| 52 | 
            +
                    with_store_management do |store|
         | 
| 53 | 
            +
                      store.set_session({"rack.session.options" => {}}, "rabbit", @white_rabbit)
         | 
| 54 | 
            +
                      store.get_session({}, "rabbit").should === ["rabbit", @white_rabbit]
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  it "should write the data with expiration time" do
         | 
| 59 | 
            +
                    with_store_management do |store|
         | 
| 60 | 
            +
                      store.set_session({"rack.session.options" => {:expires_in => 1.second}}, "rabbit", @white_rabbit)
         | 
| 61 | 
            +
                      store.get_session({}, "rabbit").should === ["rabbit", @white_rabbit]; sleep 2
         | 
| 62 | 
            +
                      store.get_session({}, "rabbit").should === ["rabbit", {}]
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  private
         | 
| 67 | 
            +
                    def instantiate_store(params={})
         | 
| 68 | 
            +
                      ActionController::Session::RedisSessionStore.new(app, params).instance_variable_get(:@pool)
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    def with_store_management
         | 
| 72 | 
            +
                      yield @store
         | 
| 73 | 
            +
                      yield @dstore
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         |