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.
Note that memcache does drop data before it may be listed to expire. For a full description of behaviour, please see memcache’s documentation.
(Not documented)
# 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
(Not documented)
# 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
(Not documented)
# 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
(Not documented)
# 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.