Class: RSence::SessionStorage
- Inherits:
-
Object
- Object
- RSence::SessionStorage
- Defined in:
- lib/rsence/sessionstorage.rb
Overview
SessionStorage doesn’t do anything by itself, it’s simply the superclass for SessionManager that does all the boring housekeeping duties.
Spliced of as a separate file to reduce the complexity of SessionManager.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#accept_requests ⇒ Object
readonly
Returns the value of attribute accept_requests.
-
#db ⇒ Object
Returns the value of attribute db.
Instance Method Summary collapse
-
#create_session_table ⇒ Object
Creates the ‘rsence_session’ table, if necessary This table is used to store sessions.
-
#create_uploads_table ⇒ Object
Creates the ‘rsence_uploads’ table, if necessary This table is used for storing temporary uploads before processing.
-
#create_version_table ⇒ Object
Creates the ‘rsence_version’ table, if necessary This table is used to check for the need of future database upgrades.
- #db_close ⇒ Object
-
#db_init ⇒ Object
Checks database connectivity and loads stored sessions from the database.
- #db_open ⇒ Object
- #db_test ⇒ Object
-
#expire_session(ses_id) ⇒ Object
Expires a session by its identifier.
-
#expire_sessions ⇒ Object
Expires all sessions that meet the timeout criteria.
-
#initialize ⇒ SessionStorage
constructor
A new instance of SessionStorage.
-
#new_ses_id(cookie_key, ses_key, timeout_secs, user_id = 0) ⇒ Object
Returns a new, unique session identifier by storing the params to the database.
-
#reset_sessions ⇒ Object
Deletes all rows from rsence_session as well as rsence_uploads.
-
#restore_sessions ⇒ Object
Restores all saved sessions from db to ram.
-
#shutdown ⇒ Object
Shut-down signal, triggers store_sessions for now.
-
#store_sessions ⇒ Object
Stores all sessions to db from ram.
-
#table_version ⇒ Object
returns the version in the rsence_version table.
Constructor Details
#initialize ⇒ SessionStorage
Returns a new instance of SessionStorage.
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 |
# File 'lib/rsence/sessionstorage.rb', line 27 def initialize ## Session data storage (by ses_id) @sessions = {} ## Session id by key @session_keys = {} ## Session id by cookie key @session_cookie_keys = {} @clone_origins = { # id => [ id, id, id ... ] } @clone_sources = { # id => id } @clone_targets = { # id => [ id, id, id ... ] } ## Disposable keys (new ses_key each request) @config = RSence.config[:session_conf] @db_uri = RSence.config[:database][:ses_db] if db_test @db_avail = true db_init else @db_avail = false puts "Warning: Session database is not available. Can't use persistent sessions." @id_counter = 0 end @accept_requests = true end |
Instance Attribute Details
#accept_requests ⇒ Object (readonly)
Returns the value of attribute accept_requests.
65 66 67 |
# File 'lib/rsence/sessionstorage.rb', line 65 def accept_requests @accept_requests end |
#db ⇒ Object
Returns the value of attribute db.
26 27 28 |
# File 'lib/rsence/sessionstorage.rb', line 26 def db @db end |
Instance Method Details
#create_session_table ⇒ Object
Creates the ‘rsence_session’ table, if necessary This table is used to store sessions
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/rsence/sessionstorage.rb', line 113 def create_session_table db_open unless @db.table_exists?(:rsence_session) puts "Creating session table..." if RSence.args[:verbose] @db.create_table :rsence_session do primary_key( :id ) column( :cookie_key, String ) column( :ses_key, String ) column( :ses_timeout, Integer ) column( :user_id, Integer ) column( :ses_active, TrueClass ) column( :ses_stored, Integer ) column( :ses_data, File ) end end db_close end |
#create_uploads_table ⇒ Object
Creates the ‘rsence_uploads’ table, if necessary This table is used for storing temporary uploads before processing
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/rsence/sessionstorage.rb', line 147 def create_uploads_table db_open unless @db.table_exists?(:rsence_uploads) puts "Creating uploads table..." if RSence.args[:verbose] @db.create_table :rsence_uploads do primary_key( :id ) foreign_key( :ses_id, :rsence_session ) column( :upload_date, Integer ) column( :upload_done, Integer ) column( :ticket_id, String ) column( :file_size, Integer ) column( :file_name, String ) column( :file_mime, String ) column( :file_data, File ) end end db_close end |
#create_version_table ⇒ Object
Creates the ‘rsence_version’ table, if necessary This table is used to check for the need of future database upgrades
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/rsence/sessionstorage.rb', line 133 def create_version_table db_open unless @db.table_exists?(:rsence_version) puts "Creating version info table..." if RSence.args[:verbose] @db.create_table :rsence_version do Integer :version end @db[:rsence_version].insert(:version => 586) end db_close end |
#db_close ⇒ Object
98 99 100 |
# File 'lib/rsence/sessionstorage.rb', line 98 def db_close @db.disconnect end |
#db_init ⇒ Object
Checks database connectivity and loads stored sessions from the database
175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rsence/sessionstorage.rb', line 175 def db_init create_session_table create_version_table create_uploads_table ## Used for future upgrades: # version = table_version return true end |
#db_open ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/rsence/sessionstorage.rb', line 102 def db_open # work-around for windows (drive letters causing confusion) if @db_uri.start_with?('sqlite://') @db = Sequel.sqlite( @db_uri.split('sqlite://')[1] ) else @db = Sequel.connect(@db_uri) end end |
#db_test ⇒ Object
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 |
# File 'lib/rsence/sessionstorage.rb', line 67 def db_test begin db_open if @db.table_exists?(:rsence_test) @db.drop_table(:rsence_test) end @db.create_table(:rsence_test) { primary_key :id; String :test } test_id = @db[:rsence_test].insert( :test => 'TestFoo' ) @db[:rsence_test].filter( :id => test_id ).update( :test => 'TestFoo2' ) @db[:rsence_test].filter( :id => test_id ).delete @db[:rsence_test].delete @db.drop_table(:rsence_test) db_close return true rescue => e if RSence.args[:debug] err_msg = [ "ERROR: SessionStorage couldn't open database", "#{e.class.to_s}, #{e.}", "Backtrace:", "\t"+e.backtrace.join("\n\t") ].join("\n")+"\n" $stderr.write( err_msg ) elsif RSence.args[:verbose] puts "Failed to open database '#{@db_uri}'." puts "Run RSence in debug mode for full error output." end return false end end |
#expire_session(ses_id) ⇒ Object
Expires a session by its identifier
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/rsence/sessionstorage.rb', line 296 def expire_session( ses_id ) return unless @sessions.has_key? ses_id ses_data = @sessions[ ses_id ] # Makes the session invalid for xhr's by deleting its key @session_keys.delete( ses_data[:ses_key] ) # Makes the session invalid for all requests by deleting its cookie key @session_cookie_keys.delete( ses_data[:cookie_key] ) # Deletes the session data itself @sessions.delete( ses_id ) # Removes all ticket-based storage bound to the session if @plugins @plugins.delegate( :expire_ses, ses_data ) @plugins.delegate( :expire_ses_id, ses_id ) end # target -> source cleanup if @clone_sources.has_key?( ses_id ) source_id = @clone_sources[ ses_id ] @clone_sources.delete( ses_id ) if @clone_sources.has_key?( ses_id ) @clone_targets[ source_id ].delete( ses_id ) if @clone_targets.has_key?( source_id ) end # source -> targets cleanup if @clone_targets.has_key?( ses_id ) @clone_targets[ ses_id ].each do |target_id| @clone_sources.delete( target_id ) if @clone_sources.has_key?( target_id ) end @clone_targets.delete( ses_id ) if @clone_targets.has_key?( ses_id ) end if @db_avail db_open # Deletes the session's row from the database @db[:rsence_uploads].filter(:ses_id => ses_id).delete @db[:rsence_session].filter(:id => ses_id).delete db_close end end |
#expire_sessions ⇒ Object
Expires all sessions that meet the timeout criteria
343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/rsence/sessionstorage.rb', line 343 def expire_sessions # Loop through all sessions in memory: @sessions.each_key do |ses_id| timed_out = @sessions[ ses_id ][:timeout] < Time.now.to_i ## Deletes the session, if the session is too old expire_session( ses_id ) if timed_out end end |
#new_ses_id(cookie_key, ses_key, timeout_secs, user_id = 0) ⇒ Object
Returns a new, unique session identifier by storing the params to the database
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/rsence/sessionstorage.rb', line 279 def new_ses_id( , ses_key, timeout_secs, user_id=0 ) unless @db_avail @id_counter += 1 return @id_counter end db_open new_id = @db[:rsence_session].insert( :cookie_key => , :ses_key => ses_key, :ses_timeout => timeout_secs, :user_id => user_id ) db_close return new_id end |
#reset_sessions ⇒ Object
Deletes all rows from rsence_session as well as rsence_uploads
188 189 190 191 192 193 194 195 196 197 |
# File 'lib/rsence/sessionstorage.rb', line 188 def reset_sessions unless @db_avail puts "Warning: Can't reset sessions: No database!" if RSence.args[:verbose] return end db_open @db[:rsence_session].delete if @db.table_exists?(:rsence_session) @db[:rsence_uploads].delete if @db.table_exists?(:rsence_uploads) db_close end |
#restore_sessions ⇒ Object
Restores all saved sessions from db to ram
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/rsence/sessionstorage.rb', line 200 def restore_sessions unless @db_avail puts "Warning: Can't restore sessions: No database!" if RSence.args[:verbose] return end puts "Restoring sessions..." if RSence.args[:verbose] db_open @db[:rsence_session].all do |ses_row| ses_id = ses_row[:id] ses_data_dump = ses_row[:ses_data] if ses_data_dump == nil @db[:rsence_session].filter(:id => ses_id).delete @db[:rsence_uploads].filter(:ses_id => ses_id).delete else begin ses_data = Marshal.load( ses_data_dump ) ses_key = ses_data[:ses_key] @sessions[ses_id] = ses_data @session_keys[ ses_key ] = ses_id @session_cookie_keys[ ses_data[:cookie_key] ] = ses_id if @plugins @plugins.delegate( :load_ses_id, ses_id ) @plugins.delegate( :load_ses, ses_data ) end rescue => e warn "Unable to load session: #{ses_id}, because: #{e.}" @db[:rsence_session].filter(:id => ses_id).delete @db[:rsence_uploads].filter(:ses_id => ses_id).delete end end end db_close end |
#shutdown ⇒ Object
Shut-down signal, triggers store_sessions for now
270 271 272 273 274 275 |
# File 'lib/rsence/sessionstorage.rb', line 270 def shutdown @accept_requests = false puts "Session shutdown in progress..." if RSence.args[:verbose] store_sessions puts "Session shutdown complete." if RSence.args[:verbose] end |
#store_sessions ⇒ Object
Stores all sessions to db from ram
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/rsence/sessionstorage.rb', line 236 def store_sessions unless @db_avail puts "Warning: Can't store sessions: No database!" if RSence.args[:verbose] return end puts "Storing sessions..." if RSence.args[:verbose] db_open ses_ids = @sessions.keys ses_ids.each do |ses_id| ses_data = @sessions[ses_id] if @plugins @plugins.delegate( :dump_ses, ses_data ) @plugins.delegate( :dump_ses_id, ses_id ) end begin ses_data_dump = Marshal.dump( ses_data ) @db[:rsence_session].filter( :id => ses_id ).update( :cookie_key => ses_data[:cookie_key], :ses_key => ses_data[:ses_key], :user_id => ses_data[:user_id], :ses_data => ses_data_dump.to_sequel_blob, :ses_timeout => ses_data[:timeout], :ses_stored => Time.now.to_i ) rescue => e warn "Unable to dump session: #{ses_id}, because: #{e.}" end end db_close end |
#table_version ⇒ Object
returns the version in the rsence_version table
167 168 169 170 171 172 |
# File 'lib/rsence/sessionstorage.rb', line 167 def table_version db_open rsence_version = @db[:rsence_version].select(:version).all[0][:version] db_close return rsence_version end |