Class: Arrow::Session

Inherits:
Object
  • Object
show all
Extends:
Configurability
Includes:
Enumerable, PluginFactory
Defined in:
lib/arrow/session.rb

Overview

The Arrow::Session class, a container for maintaining state across multiple transactions.

Authors

  • Michael Granger

Please see the file LICENSE in the top-level directory for licensing details.

Defined Under Namespace

Classes: DbStore, FileLock, FileStore, Id, Lock, MD5Id, NullLock, PosixLock, SHA1Id, Store, UserTrackId

Class Attribute Summary

Instance Attribute Summary

Class Method Summary

Instance Method Summary

Methods inherited from Object

deprecate_class_method, deprecate_method, inherited

Methods included from Loggable

#log

Constructor Details

- (Session) initialize(idobj, lock, store, txn, cookie = nil) (protected)

Create a new Arrow::Session object for the given idobj (an Arrow::Session::Id object), using the given lock (an Arrow::Session::Locker object) for serializing access.

Raises:

  • (ArgumentError)


192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/arrow/session.rb', line 192

def initialize( idobj, lock, store, txn, cookie=nil )
  raise ArgumentError, "No id object" unless idobj
  raise ArgumentError, "No lock object" unless lock
  raise ArgumentError, "No store object" unless store

  self.log.debug "Initializing session with id: %p, lock: %p, store: %p" %
    [ idobj, lock, store ]

  @id = idobj
  @lock = lock
  @store = store
  @txn = txn
  @cookie = cookie

  @store[ :_session_id ] = id.to_s
end

Class Attribute Details

+ (Object) config (readonly)

Returns the value of attribute config



43
44
45
# File 'lib/arrow/session.rb', line 43

def config
  @config
end

Instance Attribute Details

The Apache::Cookie object used to manipulate the session cookie.



224
225
226
# File 'lib/arrow/session.rb', line 224

def cookie
  @cookie
end

- (Object) id (readonly)

The session’s unique identifier, an Apache::Session::Id object.



215
216
217
# File 'lib/arrow/session.rb', line 215

def id
  @id
end

- (Object) lock (readonly)

The session’s lock object; an Apache::Session::Lock.



221
222
223
# File 'lib/arrow/session.rb', line 221

def lock
  @lock
end

- (Object) store (readonly)

The session’s backing store; an Apache::Session::Store object.



218
219
220
# File 'lib/arrow/session.rb', line 218

def store
  @store
end

Class Method Details

+ (Object) configure(config)

Configure the session class’s factory with the given Arrow::Config object.



57
58
59
60
# File 'lib/arrow/session.rb', line 57

def self::configure( config )
  @config = config.dup
  Arrow::Logger[self].debug "Done. Session config is: %p" % @config
end

+ (Object) create(txn, configHash = {})

Create a new session for the specified request.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/arrow/session.rb', line 64

def self::create( txn, configHash={} )
  # Merge the incoming config with the factory's
  sconfig = @config.merge( configHash )
  Arrow::Logger[self].debug "Merged config is: %p" % sconfig

  # Create a new id and backing store object
      idobj = self.create_id( sconfig, txn )
      store = self.create_store( sconfig, idobj )
      lock = self.create_lock( sconfig, store, idobj )

  # Create the session cookie
      scookie = self.create_session_cookie( txn, sconfig, idobj, store, lock )

  return new( idobj, lock, store, txn, scookie )
end

+ (Object) create_id(config, txn)

Create an Arrow::Session::Id object for the given txn, with the particulars dictated by the specified config.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/arrow/session.rb', line 97

def self::create_id( config, txn )
  cookie_name = config.idName

      # Fetch the id from the request, either from the session cookie or
  # as a parameter if the cookie doesn't exist.
  if txn.request_cookies.include?( cookie_name )
    Arrow::Logger[self].debug "Found an existing session cookie (%s)" %
      [ cookie_name ]
    idstring = txn.request_cookies[ cookie_name ].value
  else
    Arrow::Logger[self].debug \
      "No existing session cookie (%s); looking for one in a request parameter" %
      [ cookie_name]
    idstring = txn.param( cookie_name )
  end

  Arrow::Logger[self].debug "Creating a session id object: %p" % config.idType
  return Arrow::Session::Id.create( config.idType, txn.request, idstring )
end

+ (Object) create_lock(config, store, id)

Create an Arrow::Session::Lock object for the specified store and id.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/arrow/session.rb', line 128

def self::create_lock( config, store, id )
    
  lockuri = Arrow::Session.parse_uri( config.lockType )
      lock = nil

  # If the configuration says to use the recommended locker, ask the
  # backing store for a lock object.
  if lockuri.scheme == 'recommended'
    Arrow::Logger[self].debug "Creating recommended lock"
    lock = store.create_recommended_lock( id ) or
      raise Arrow::SessionError, "No recommended locker for %s" %
        store.class.name
  else
    Arrow::Logger[self].debug "Creating a session lock: %p" % lockuri
    lock = Arrow::Session::Lock.create( lockuri, id )
  end

   return lock
end

Set the session cookie if we’re really running under Apache.



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/arrow/session.rb', line 82

def self::create_session_cookie( txn, config, id, store, lock )
scookie = Arrow::Cookie.new(
    config.idName,
    id.to_s,
    :expires => config.expires,
    :path => '/'
  )

Arrow::Logger[self].debug "Created cookie: %p" % scookie.to_s
    return scookie
end

+ (Object) create_store(config, id)

Create an Arrow::Session::Store object with the given id. The type and configuration of the store will be dictated by the specified config object.



121
122
123
124
# File 'lib/arrow/session.rb', line 121

def self::create_store( config,  id )
    Arrow::Logger[self].debug "Creating a session store: %p" % config.storeType
return Arrow::Session::Store.create( config.storeType, id )
end

+ (Object) def_delegated_readers(*syms) (protected)

Create delegators that readlock the session store before accessing it.



162
163
164
165
166
167
168
169
# File 'lib/arrow/session.rb', line 162

def self::def_delegated_readers( *syms )
  syms.each do |sym|
    define_method( sym ) do |*args|
      @lock.read_lock
      @store.send( sym, *args )
    end
  end
end

+ (Object) def_delegated_writers(*syms) (protected)

Create delegators that writelock the session store before accessing it.



174
175
176
177
178
179
180
181
# File 'lib/arrow/session.rb', line 174

def self::def_delegated_writers( *syms )
  syms.each do |sym|
    define_method( sym ) do |*args|
      @lock.write_lock
      @store.send( sym, *args )
    end
  end
end

+ (Object) parse_uri(str)

Parse the given string into a URI object, appending the path part if it doesn’t exist.



48
49
50
51
52
# File 'lib/arrow/session.rb', line 48

def self::parse_uri( str )
  return str if str.is_a?( URI::Generic )
  str += ":." if /^\w+$/ =~ str
  URI.parse( str )
end

Return the configured name of the session cookie.



150
151
152
# File 'lib/arrow/session.rb', line 150

def self::session_cookie_name
  return @config.idName
end

Instance Method Details

- (Object) clear

Clear all data from the session object.



238
239
240
241
242
243
# File 'lib/arrow/session.rb', line 238

def clear
  @lock.with_write_lock do
      @store.clear
      @store[ :_session_id ] = @id.to_s
  end
end

- (Object) each(&block)

Enumerable iterface: iterate over the session’s key/value pairs, calling the given block once for each pair.

Raises:

  • (LocalJumpError)


248
249
250
251
252
# File 'lib/arrow/session.rb', line 248

def each( &block )
  raise LocalJumpError, "no block given" unless block
  @lock.read_lock
  @store.each( &block )
end

- (Object) finish

Tell the session that it will not be used again in the current session.



272
273
274
# File 'lib/arrow/session.rb', line 272

def finish
  @lock.release_all_locks
end

- (Object) remove

Delete the session



228
229
230
231
232
233
234
# File 'lib/arrow/session.rb', line 228

def remove
  @lock.with_write_lock do
    @store.remove
  end
  @lock.release_all_locks
  @cookie.expires = Time.at(0)
end

- (Object) save

Save the session to fixed storage and set the session cookie in the creating transaction’s outgoing headers.



257
258
259
260
261
262
263
264
265
266
267
# File 'lib/arrow/session.rb', line 257

def save
  begin
    self.log.debug "Saving session data"
    @store.save
    self.log.debug "Writing session cookie (%p)" % [ @cookie ]
    @txn.cookies[ self.class.session_cookie_name ] = @cookie
  ensure
    self.log.debug "Releasing all locks"
    @lock.release_all_locks
  end
end