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, {}
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
87:
88:
89:
90:
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:
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:
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