On Monday, July 25, 2011 at 2:22 PM, Neil wrote:
While it's entirely possible that this issue is caused by some other
factor, but we are getting session collisions as well as an issue
where one user is getting another user's session. This is clearly
bad, but I cannot for the life of me figure out how this could even
happen in the first place. The code looks thread safe to me, and a
quick discussion on #ruby-lang seems to support that.
Thoughts:
1. Session IDs are being generated in the same sequence (uses
securerandom -> openssl which does not have a static seed)
2. Threads. Looks good to me.
3. Maybe memcached is returning something other than "STORED/
NOT_STORED" for @pool.add(sid, session), but the operation still
succeeded?
4. Gnomes.
Any input is GREATLY appreciated. Please don't say "it's an RC, what
do you expect?" :)
From https://github.com/rack/rack/blob/master/lib/rack/session/memcache.rb
def generate_sid
loop do
sid = super
break sid unless @pool.get(sid, true)
end
end
def get_session(env, sid)
with_lock(env, [nil, {}]) do
unless sid and session = @pool.get(sid)
sid, session = generate_sid, {}
unless /^STORED/ =~ @pool.add(sid, session)
raise "Session collision on '#{sid.inspect}'"
end
end
[sid, session]
end
end
def set_session(env, session_id, new_session, options)
expiry = options[:expire_after]
expiry = expiry.nil? ? 0 : expiry + 1
with_lock(env, false) do
@pool.set session_id, new_session, expiry
session_id
end
end