Class: N::App::Session

Inherits:
Hash
  • Object
show all
Defined in:
lib/n/app/session.rb

Overview

Session

This object encapsulates a WebApplication session.

Design:

The session should be persistable to survive server shutdowns.

Usage

State is a neccessary evil but try to avoid using session variables as much as possible. Session state is typically distributed to many servers so avoid storing complete objects in session variables, only store oids and integer/strings.

Constant Summary collapse

"nsid"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sid, request = nil) ⇒ Session

Returns a new instance of Session.



129
130
131
132
133
134
# File 'lib/n/app/session.rb', line 129

def initialize(sid, request = nil)
	super()
	@session_id = sid
	@touch_time = Time.now
	@user = N::AnonymousUser.instance()
end

Instance Attribute Details

#session_idObject (readonly)

Returns the value of attribute session_id.



116
117
118
# File 'lib/n/app/session.rb', line 116

def session_id
  @session_id
end

#touch_timeObject

the last touch time



125
126
127
# File 'lib/n/app/session.rb', line 125

def touch_time
  @touch_time
end

#userObject

keep the user to allow for session lookup based on user. also do NOT keep the full user as an object in the session hash to optimize druby usage!



122
123
124
# File 'lib/n/app/session.rb', line 122

def user
  @user
end

Class Method Details

.calculate_idObject

Calculates a unique id.

The session id must be unique, a monotonically increasing function like time is appropriate. Random may produce equal ids? add a prefix (SALT) to stop hackers from creating session_ids.

TODO: make the prefix configurable



201
202
203
204
205
206
# File 'lib/n/app/session.rb', line 201

def self.calculate_id
	time = Time.now
	# FIXME: make this more random? 
	id = Digest::MD5.md5("SALT#{time.to_i} #{time.tv_usec}").to_s
	return id
end

.initialize_gc(session_manager, interval) ⇒ Object

Initialize sessions garbage collection.

Warning: this is not used yet!



212
213
214
215
216
217
218
219
220
# File 'lib/n/app/session.rb', line 212

def self.initialize_gc(session_manager, interval)
	# gmosx, FIXME: store this in a variable.
	Thread.new {
		loop do
			sleep(interval)
			garbage_collect(session_manager.sessions)
		end
	}
end

Instance Method Details

#login(request, user) ⇒ Object

Login a user

Returns false for banned users.



140
141
142
143
144
145
146
147
# File 'lib/n/app/session.rb', line 140

def (request, user)
	return false if user.banned? 
	@user = user
	@user.(request)
	$sessions.(@user.oid, @user.name)
	$log.info "User '#{user}' logged in!"
	return true
end

#logoutObject

Logout a user



151
152
153
154
155
156
157
# File 'lib/n/app/session.rb', line 151

def logout()
	self.clear()
	@user.logout()
	$sessions.logout(@user.oid)
	$log.info "User '#{user}' logged out!"
	@user = N::AnonymousUser.instance
end

#refresh!Object

Refresh session entities.

Call this when you manually change entities stored in the session. A typical scenario is when you change an online user.

Warning: the current version only refreshes the “USER” entity.



188
189
190
# File 'lib/n/app/session.rb', line 188

def refresh!
	@user = $db.get(@user.oid, @user.class) if @user
end

#stale?Boolean

Returns:

  • (Boolean)


167
168
169
170
# File 'lib/n/app/session.rb', line 167

def stale?
	timeout = @user.anonymous? ? $srv_anon_session_timeout : $srv_session_timeout
	return (Time.now - @touch_time > timeout)
end

#synchronize!Object

call this method to synchronize the session with other servers in the cluster.



175
176
177
178
179
# File 'lib/n/app/session.rb', line 175

def synchronize!
	# gmosx: TODO, add a check if the session is allready
	# synchronized.
	$sessions[@session_id] = self
end

#touchObject



161
162
163
# File 'lib/n/app/session.rb', line 161

def touch
	@touch_time = Time.now
end