Abstract::ID
Rack::Session::Memcache provides simple cookie based session management. Session data is stored in memcached. The corresponding session key is maintained in the cookie. You may treat Session::Memcache as you would Session::Pool with the following caveats.
Setting :expire_after to 0 would note to the Memcache server to hang onto the session data until it would drop it according to it’s own specifications. However, the cookie sent to the client would expire immediately.
Note that memcache does drop data before it may be listed to expire. For a full description of behaviour, please see memcache’s documentation.
# File lib/rack/session/memcache.rb, line 28 28: def initialize(app, options={}) 29: super 30: 31: @mutex = Mutex.new 32: mserv = @default_options[:memcache_server] 33: mopts = @default_options. 34: reject{|k,v| !MemCache::DEFAULT_OPTIONS.include? k } 35: @pool = MemCache.new mserv, mopts 36: unless @pool.active? and @pool.servers.any?{|c| c.alive? } 37: raise 'No memcache servers' 38: end 39: end
# File lib/rack/session/memcache.rb, line 41 41: def generate_sid 42: loop do 43: sid = super 44: break sid unless @pool.get(sid, true) 45: end 46: end
# File lib/rack/session/memcache.rb, line 48 48: def get_session(env, session_id) 49: @mutex.lock if env['rack.multithread'] 50: unless session_id and session = @pool.get(session_id) 51: session_id, session = generate_sid, {} 52: unless /^STORED/ =~ @pool.add(session_id, session) 53: raise "Session collision on '#{session_id.inspect}'" 54: end 55: end 56: session.instance_variable_set '@old', @pool.get(session_id, true) 57: return [session_id, session] 58: rescue MemCache::MemCacheError, Errno::ECONNREFUSED 59: # MemCache server cannot be contacted 60: warn "#{self} is unable to find memcached server." 61: warn $!.inspect 62: return [ nil, {} ] 63: ensure 64: @mutex.unlock if @mutex.locked? 65: end
# File lib/rack/session/memcache.rb, line 67 67: def set_session(env, session_id, new_session, options) 68: expiry = options[:expire_after] 69: expiry = expiry.nil? ? 0 : expiry + 1 70: 71: @mutex.lock if env['rack.multithread'] 72: if options[:renew] or options[:drop] 73: @pool.delete session_id 74: return false if options[:drop] 75: session_id = generate_sid 76: @pool.add session_id, {} # so we don't worry about cache miss on #set 77: end 78: 79: session = @pool.get(session_id) || {} 80: old_session = new_session.instance_variable_get '@old' 81: old_session = old_session ? Marshal.load(old_session) : {} 82: 83: unless Hash === old_session and Hash === new_session 84: env['rack.errors']. 85: puts 'Bad old_session or new_session sessions provided.' 86: else # merge sessions 87: # alterations are either update or delete, making as few changes as 88: # possible to prevent possible issues. 89: 90: # removed keys 91: delete = old_session.keys - new_session.keys 92: if $VERBOSE and not delete.empty? 93: env['rack.errors']. 94: puts "//@#{session_id}: delete #{delete*','}" 95: end 96: delete.each{|k| session.delete k } 97: 98: # added or altered keys 99: update = new_session.keys. 100: select{|k| new_session[k] != old_session[k] } 101: if $VERBOSE and not update.empty? 102: env['rack.errors'].puts "//@#{session_id}: update #{update*','}" 103: end 104: update.each{|k| session[k] = new_session[k] } 105: end 106: 107: @pool.set session_id, session, expiry 108: return session_id 109: rescue MemCache::MemCacheError, Errno::ECONNREFUSED 110: # MemCache server cannot be contacted 111: warn "#{self} is unable to find memcached server." 112: warn $!.inspect 113: return false 114: ensure 115: @mutex.unlock if @mutex.locked? 116: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.