Class: Arrow::Session::Store
- Inherits:
-
Arrow::Object
- Object
- Arrow::Object
- Arrow::Session::Store
- Extends:
- Forwardable
- Includes:
- PluginFactory
- Defined in:
- lib/arrow/session/store.rb
Overview
The Arrow::Session::Store class, a derivative of Arrow::Object. Instances of concrete deriviatives of this class provide serialization and semi-permanent storage of session data for Arrow::Session objects.
Derivative Interface ===
In order to create your own session store classes, you need to provide four methods: #insert, #update, #retrieve, #remove. All but one of the methods provides serialization and marking records as dirty in the base class, so unless you want to manage these tasks yourself, you should super() to the parent’s implementation with a block. Examples are provided for each method.
#insert | Insert a new session into the backing store. Example: def insert super {|data| @io.print(data) } end |
#update | Update an existing session’s data in the backing store. Example: def update super {|data| @io.rewind; @io.truncate(0); @io.print(data) } end |
#retrieve | Retrieve the serialized session data from the backing store. Example: def retrieve super { @io.rewind; @io.read } end |
#delete | Delete the session from the backing store. Example: def delete super {|data| @io.close; File.delete(@session_file) } end |
Optional Derivative Interface ===
Serialization ====
If you want to use something other than Marshal for object serialization, you can override the protected methods #serialized_data and #serialized_data= to provide your own serialization.
#serialized_data | Serialize the data in the instance variable @data and return it. |
#serialized_data=( serialized ) | Deserialize the given serialized data and assign it to @data. |
Example (serializing to YAML instead of binary):
require 'yaml' def serialized_data @data.to_yaml end def serialized_data=( data ) @data = YAML.load( data ) end
Lock Recommendation ====
If arrow is configured to use the ‘recommended’ session lock, your session store can recommend one it knows will work (e.g., if your session store is a database, you can recommend a lock that uses database locking). The simple way to do that is to define a RecommendedLocker constant in your class which contains the URI of the locker you wish to use. If you need more control than the URI can provide, you can also override the #create_recommended_lock method, which should return an instance of the locker that should be used.
The method will be given the instantiated Arrow::Session::Id object that identifies the session so that you can derive a filename, primary key, etc.
Example:
def create_recommended_lock( idobj ) return DBITransactionLock.new( idobj.to_s ) end
Authors
Michael Granger
Please see the file LICENSE in the top-level directory for licensing details.
Constant Summary
- RecommendedLocker =
The URI of the lock class recommended for use with this Store.
URI.parse( 'file:.' )
- DelegatedMethods =
The methods which are delegate directly to the data hash.
[ :[], :default, :default=, :each, :each_key, :each_pair, :each_value, :empty?, :fetch, :has_key?, :has_value?, :include?, :index, :invert, :keys, :length, :member?, :merge, :rehash, :reject, :select, :size, :sort, :to_a, :value?, :values ]
Instance Attribute Summary
-
- (Object) data
readonly
The raw session data hash.
Class Method Summary
-
+ (Object) create(uri, idobj)
Overridden factory method: handle a URI object or a name.
-
+ (Object) derivativeDirs
Returns the Array of directories to search for derivatives; part of the PluginFactory interface.
Instance Method Summary
-
- (Object) []=(key, value)
(also: #store)
Set the value for the specified key.
-
- (Object) clear
Clear all key/value pairs from the store for this session.
-
- (Object) create_recommended_lock(idobj)
Returns an instance of the recommended lock object for the receiving store.
-
- (Store) initialize(uri, idobj)
constructor
Create a new Arrow::Session::Store object.
-
- (Object) insert {|self.serialized_data| ... }
Insert the current data hash into whatever permanent storage the Store object is acting as an interface to.
-
- (Object) merge!(other, &block)
(also: #update)
Adds the contents of the other hash to the session data, overwriting entries in the session data with values from the other hash where there are duplicates.
-
- (Boolean) modified?
Returns true if the receiver’s data is out of sync with the data in the backing store.
-
- (Boolean) new?
Returns true if the data in the receiver has not yet been saved to the backing store, or if the entry in the backing store has been deleted since it was last saved.
-
- (Object) reject!(&block)
(also: #delete_if)
Deletes every key-value pair from the session data for which the block evaluates to true.
-
- (Object) remove
Permanently remove the data hash associated with the id used in the receiver’s creation from permanent storage.
-
- (Object) replace(other)
Replace the contents of the session hash with those of the given other hash.
-
- (Object) retrieve
Retrieve the data hash stored in permanent storage associated with the id the object was created with.
-
- (Object) save
Save the session data to the backing store.
-
- (Object) serialized_data
protected
Returns the data in the session store as a serialized object.
-
- (Object) serialized_data(string)
protected
Sets the session’s data by deserializing the object contained in the given string.
Methods inherited from Arrow::Object
deprecate_class_method, deprecate_method, inherited
Methods included from Arrow::Loggable
Constructor Details
- (Store) initialize(uri, idobj)
Create a new Arrow::Session::Store object.
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/arrow/session/store.rb', line 135 def initialize( uri, idobj ) @data = {} @id = idobj @new = true @modified = false unless idobj.new? self.retrieve end super() end |
Instance Attribute Details
- (Object) data (readonly)
The raw session data hash
158 159 160 |
# File 'lib/arrow/session/store.rb', line 158 def data @data end |
Class Method Details
+ (Object) create(uri, idobj)
Overridden factory method: handle a URI object or a name
123 124 125 126 |
# File 'lib/arrow/session/store.rb', line 123 def self::create( uri, idobj ) uri = Arrow::Session.parse_uri( uri ) if uri.is_a?( String ) super( uri.scheme.dup, uri, idobj ) end |
+ (Object) derivativeDirs
Returns the Array of directories to search for derivatives; part of the PluginFactory interface.
117 118 119 |
# File 'lib/arrow/session/store.rb', line 117 def self::derivativeDirs [ 'arrow/session', 'arrow/session/store' ] end |
Instance Method Details
- (Object) []=(key, value) Also known as: store
Set the value for the specified key.
162 163 164 165 |
# File 'lib/arrow/session/store.rb', line 162 def []=( key, value ) @data[ key ] = value @modified = true end |
- (Object) clear
Clear all key/value pairs from the store for this session.
183 184 185 186 |
# File 'lib/arrow/session/store.rb', line 183 def clear @data.clear @modified = true end |
- (Object) create_recommended_lock(idobj)
Returns an instance of the recommended lock object for the receiving store. If no recommended locking strategy is known, this method raises a SessionError.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/arrow/session/store.rb', line 294 def create_recommended_lock( idobj ) self.log.debug "Searching for recommended lock for %s" % self.class.name # Traverse the class hierarchy to find a class which defines a # RecommendedLocker constant adviceClass = self.class.ancestors.find {|klass| klass.const_defined?( :RecommendedLocker ) } or raise SessionError, "No recommended locker for %p" % self.class.ancestors uri = adviceClass.const_get( :RecommendedLocker ) or raise SessionError, "Could not fetch RecommendedLocker constant" self.log.debug "Creating recommended lock %s" % uri uri = Arrow::Session.parse_uri( uri ) if uri.is_a?( String ) lock = Arrow::Session::Lock.create( uri, idobj ) self.log.debug "Created recommended lock object: %p" % lock return lock end |
- (Object) insert {|self.serialized_data| ... }
Insert the current data hash into whatever permanent storage the Store object is acting as an interface to. Concrete implementations should provide an overriding implementation of this method that calls #super with a block which will be called with the serialized data that should be stored.
253 254 255 256 257 |
# File 'lib/arrow/session/store.rb', line 253 def insert self.log.debug "Inserting session data for key %s" % @id yield( self.serialized_data ) @new = @modified = false end |
- (Object) merge!(other, &block) Also known as: update
Adds the contents of the other hash to the session data, overwriting entries in the session data with values from the other hash where there are duplicates. If a block is given, it is called for each duplicate key, and the return value is the value set in the hash.
194 195 196 197 198 |
# File 'lib/arrow/session/store.rb', line 194 def merge!( other, &block ) # :yields: key, sessionValue, otherValue @data.merge!( other, &block ) ensure @modified = true end |
- (Boolean) modified?
Returns true if the receiver’s data is out of sync with the data in the backing store.
224 225 226 |
# File 'lib/arrow/session/store.rb', line 224 def modified? @modified end |
- (Boolean) new?
Returns true if the data in the receiver has not yet been saved to the backing store, or if the entry in the backing store has been deleted since it was last saved.
232 233 234 |
# File 'lib/arrow/session/store.rb', line 232 def new? @new end |
- (Object) reject!(&block) Also known as: delete_if
Deletes every key-value pair from the session data for which the block evaluates to true.
213 214 215 216 217 218 |
# File 'lib/arrow/session/store.rb', line 213 def reject!( &block ) # :yields: key, value rval = @data.reject!( &block ) return rval ensure @modified = true if rval end |
- (Object) remove
Permanently remove the data hash associated with the id used in the receiver’s creation from permanent storage.
285 286 287 288 |
# File 'lib/arrow/session/store.rb', line 285 def remove self.log.debug "Removing session data for key %s" % @id @new = true end |
- (Object) replace(other)
Replace the contents of the session hash with those of the given other hash.
204 205 206 207 208 |
# File 'lib/arrow/session/store.rb', line 204 def replace( other ) @data.replace( other ) ensure @modified = true end |
- (Object) retrieve
Retrieve the data hash stored in permanent storage associated with the id the object was created with. Concrete implementations should provide an overriding implementation of this method that calls #super with a block that returns the serialized data to be restored.
276 277 278 279 280 |
# File 'lib/arrow/session/store.rb', line 276 def retrieve self.log.debug "Retrieving session data for key %s" % @id self.serialized_data = yield @new = @modified = false end |
- (Object) save
Save the session data to the backing store
238 239 240 241 242 243 244 245 |
# File 'lib/arrow/session/store.rb', line 238 def save return false unless self.modified? || self.new? if self.new? self.insert else self.update end end |
- (Object) serialized_data (protected)
Returns the data in the session store as a serialized object.
324 325 326 327 |
# File 'lib/arrow/session/store.rb', line 324 def serialized_data data = strip_hash( @data ) return Marshal.dump( data ) end |
- (Object) serialized_data=(string) (protected)
Sets the session’s data by deserializing the object contained in the given string.
332 333 334 335 336 337 338 |
# File 'lib/arrow/session/store.rb', line 332 def serialized_data=( string ) if string.empty? self.log.error "No session data: retaining default hash" else @data = Marshal.restore( string ) end end |