Class: RSence::SessionStorage

Inherits:
SessionBackend
  • Object
show all
Defined in:
lib/rsence/sessionstorage.rb

Overview

SessionStorage doesn’t do anything by itself, it’s simply the superclass for SessionManager that handles the persistent storage.

Direct Known Subclasses

SessionManager

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSessionStorage

Returns a new instance of SessionStorage.



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
# File 'lib/rsence/sessionstorage.rb', line 20

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
  # workaround for the mutexes, would fail in ruby 2.0.0
  @shutdown_save = false
  @shutdown_saved = false
  Thread.new do
    Thread.pass
    until @shutdown_saved
      if @shutdown_save
        store_sessions
        @shutdown_saved = true
      end
      sleep 1
    end
  end
end

Instance Attribute Details

#accept_requestsObject (readonly)

Returns the value of attribute accept_requests.



69
70
71
# File 'lib/rsence/sessionstorage.rb', line 69

def accept_requests
  @accept_requests
end

#dbObject

Returns the value of attribute db.



19
20
21
# File 'lib/rsence/sessionstorage.rb', line 19

def db
  @db
end

#db_availObject (readonly)

Returns the value of attribute db_avail.



68
69
70
# File 'lib/rsence/sessionstorage.rb', line 68

def db_avail
  @db_avail
end

Instance Method Details

#expire_session(ses_id) ⇒ Object

Expires a session by its identifier



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/rsence/sessionstorage.rb', line 143

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
    remove_session_data( ses_id )
    sleep @config[:db_sleep]
  end
end

#expire_sessionsObject

Expires all sessions that meet the timeout criteria



186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/rsence/sessionstorage.rb', line 186

def expire_sessions

  # Loop through all sessions in memory:
  ses_ids = @sessions.keys.clone
  ses_ids.each do |ses_id|
    if @sessions[ses_id] and @sessions[ses_id].has_key?(:timeout)
      timed_out = @sessions[ ses_id ][:timeout] < Time.now.to_i
    else
      timed_out = true
    end
    ## 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



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rsence/sessionstorage.rb', line 72

def new_ses_id( cookie_key, ses_key, timeout_secs, user_id=0 )
  if @db_avail
    return insert_session_data( {
      :cookie_key  => cookie_key,
      :ses_key     => ses_key,
      :ses_timeout => timeout_secs,
      :user_id     => user_id
    } )
  else
    @id_counter += 1
    return @id_counter
  end
end

#reset_sessionsObject

Deletes all rows from rsence_session as well as rsence_uploads



124
125
126
127
128
129
130
# File 'lib/rsence/sessionstorage.rb', line 124

def reset_sessions
  unless @db_avail
    puts "Warning: Can't reset sessions: No database!" if RSence.args[:verbose]
    return
  end
  remove_all_session_data
end

#restore_session(ses_id, ses_data) ⇒ Object

Restores a single session, called from the database backend



112
113
114
115
116
117
118
119
120
121
# File 'lib/rsence/sessionstorage.rb', line 112

def restore_session( ses_id, ses_data )
  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
end

#restore_sessionsObject

Restores all saved sessions from db to ram



133
134
135
136
137
138
139
140
# File 'lib/rsence/sessionstorage.rb', line 133

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]
  load_session_data
end

#shutdownObject

Shut-down signal, triggers store_sessions for now



202
203
204
205
206
207
208
# File 'lib/rsence/sessionstorage.rb', line 202

def shutdown
  @accept_requests = false
  puts "Session shutdown in progress..." if RSence.args[:verbose]
  @shutdown_save = true
  sleep 1 until @shutdown_saved
  puts "Session shutdown complete." if RSence.args[:verbose]
end

#store_sessionsObject

Stores all sessions to db from ram



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rsence/sessionstorage.rb', line 87

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]
  ses_ids = @sessions.keys.clone
  ses_ids.each do |ses_id|
    ses_data = @sessions[ses_id]
    next if ses_data.nil?
    ses_data = @sessions[ses_id].clone
    if @plugins
      @plugins.delegate( :dump_ses, ses_data )
      @plugins.delegate( :dump_ses_id, ses_id )
    end
    begin
      store_session_data( ses_data )
      sleep @config[:db_sleep]
    rescue => e
      warn "Unable to dump session: #{ses_id}, because: #{e.message}"
    end
  end
end