/usr/lib/ruby/vendor_ruby/merb-core/dispatch/session/memory.rb is in ruby-merb-core 1.1.3+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | module Merb
# Sessions stored in memory.
#
# Set it up by adding the following to your init file:
#
# Merb::Config.use do |c|
# c[:session_store] = :memory
# c[:memory_session_ttl] = 3600 # in seconds, one hour
# end
#
# Sessions will remain in memory until the server is stopped or the time
# as set in :memory_session_ttl expires. Expired sessions are cleaned up in the
# background by a separate thread. Every time reaper
# cleans up expired sessions, garbage collection is scheduled start.
#
# Memory session is accessed in a thread safe manner.
class MemorySession < SessionStoreContainer
# The session store type
self.session_store_type = :memory
# Bypass normal implicit class attribute reader - see below.
# :api: private
def store
self.class.store
end
# Lazy load/setup of MemorySessionStore.
# :api: private
def self.store
@_store ||= MemorySessionStore.new(Merb::Config[:memory_session_ttl])
end
end
# Used for handling multiple sessions stored in memory.
class MemorySessionStore
# ==== Parameters
# ttl<Fixnum>:: Session validity time in seconds. Defaults to 1 hour.
#
# :api: private
def initialize(ttl=nil)
@sessions = Hash.new
@timestamps = Hash.new
@mutex = Mutex.new
@session_ttl = ttl || Merb::Const::HOUR # defaults 1 hour
start_timer
end
# ==== Parameters
# session_id<String>:: ID of the session to retrieve.
#
# ==== Returns
# ContainerSession:: The session corresponding to the ID.
#
# :api: private
def retrieve_session(session_id)
@mutex.synchronize {
@timestamps[session_id] = Time.now
@sessions[session_id]
}
end
# ==== Parameters
# session_id<String>:: ID of the session to set.
# data<ContainerSession>:: The session to set.
#
# :api: private
def store_session(session_id, data)
@mutex.synchronize {
@timestamps[session_id] = Time.now
@sessions[session_id] = data
}
end
# ==== Parameters
# session_id<String>:: ID of the session to delete.
#
# :api: private
def delete_session(session_id)
@mutex.synchronize {
@timestamps.delete(session_id)
@sessions.delete(session_id)
}
end
# Deletes any sessions that have reached their maximum validity.
#
# :api: private
def reap_expired_sessions
@timestamps.each do |session_id,stamp|
delete_session(session_id) if (stamp + @session_ttl) < Time.now
end
GC.start
end
# Starts the timer that will eventually reap outdated sessions.
#
# :api: private
def start_timer
Thread.new do
loop {
sleep @session_ttl
reap_expired_sessions
}
end
end
end
end
|