Hi Neil, Good to hear you figured that out. I, too, had heard mention of Dalli as a replacement for memcache-client. Perhaps we should update Rack's gemspec? - Josh On Thursday, July 28, 2011 at 10:54 PM, Neil Matatall wrote: > Joshua, > > I think what you described was indeed our issue. The call to @pool.add > actually returned "END" which is a sign of a get_multikey > > We were using memcache-client and the author informed me that the > project was no longer supported and said that this can occur when the > same memcache instance handles sessions and data. He recommended > splitting the caches as well as switching to Dalli instead. > > So...not a rack issue! > > Thanks! > Neil > > On 7/25/11 1:23 PM, Joshua Ballanco wrote: > > Have you considered the possibility that memcache might be recycling > > keys on you? > > > > We had an issue a while back where we were using memcache for both > > fragment caching and session storage. Occasionally, we would get > > exceptions in retrieving a session, and looking at the error message > > it was clear that what was retrieved from memcache was a fragment and > > not a session. Unfortunately, we moved back to a cookie-based session > > store before we had a chance to look deeper into the issue. What I can > > say is that based on the key generation scheme we were using for > > sessions and cache keys, there was effectively 0 chance that we were > > duplicating keys. Instead, it seemed like memcache was re-using slots > > for different keys when we started exhausting free slots. > > > > Hope that helps! > > > > - Joshua Ballanco > > > > 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