def set_session(env, session_id, new_session, options)
expiry = options[:expire_after]
expiry = expiry.nil? ? 0 : expiry + 1
@mutex.lock if env['rack.multithread']
if options[:renew] or options[:drop]
@pool.delete session_id
return false if options[:drop]
session_id = generate_sid
@pool.add session_id, {}
end
session = @pool.get(session_id) || {}
old_session = new_session.instance_variable_get '@old'
old_session = old_session ? Marshal.load(old_session) : {}
unless Hash === old_session and Hash === new_session
env['rack.errors'].
puts 'Bad old_session or new_session sessions provided.'
else
delete = old_session.keys - new_session.keys
if $VERBOSE and not delete.empty?
env['rack.errors'].
puts "//@#{session_id}: delete #{delete*','}"
end
delete.each{|k| session.delete k }
update = new_session.keys.
select{|k| new_session[k] != old_session[k] }
if $VERBOSE and not update.empty?
env['rack.errors'].puts "//@#{session_id}: update #{update*','}"
end
update.each{|k| session[k] = new_session[k] }
end
@pool.set session_id, session, expiry
return session_id
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
warn "#{self} is unable to find memcached server."
warn $!.inspect
return false
ensure
@mutex.unlock if @mutex.locked?
end