Class: Arrow::Session::Lock

Inherits:
Object
  • Object
show all
Includes:
PluginFactory
Defined in:
lib/arrow/session/lock.rb

Overview

The Arrow::Session::Lock class, which is the abstract superclass for session lock object classes. Locks are objects which fulfill the locking interface of Arrow::Session, providing a way of serializing access to session data.

To derive your own lock manager classes from this class, you’ll need to follow the following interface:

Derivative Interface ===

Locking is achieved via four methods: #acquire_read_lock, #acquire_write_lock, #release_read_lock, and #release_write_lock. These methods provide the #concurrency for sessions shared between multiple servers. You will probably #also want to provide your own initializer to capture the session’s ID.

#initialize( uri=string, id=Arrow::Session::Id )

#acquire_read_lock

Acquire a shared lock on the session data.

#acquire_write_lock

Acquire an exclusive lock on the session data.

#release_read_lock

Release a shared lock on the session data.
#release_write_lock

Release an exclusive lock on the session data.

Authors

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

Direct Known Subclasses

FileLock, NullLock, PosixLock

Constant Summary collapse

UNLOCKED =

Lock status flags

0b00
READ =
0b01
WRITE =
0b10

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Object

deprecate_class_method, deprecate_method, inherited

Constructor Details

#initialize(uri, id) ⇒ Lock

Create a new Arrow::Session::Lock object.



82
83
84
85
# File 'lib/arrow/session/lock.rb', line 82

def initialize( uri, id )
	super()
	@status = UNLOCKED
end

Class Method Details

.create(uri, id) ⇒ Object

Create a new Arrow::Session::Lock object for the given id of the type specified by uri.



69
70
71
72
73
# File 'lib/arrow/session/lock.rb', line 69

def self::create( uri, id )
	uri = Arrow::Session.parse_uri( uri ) if
		uri.is_a?( String )
	super( uri.scheme.dup, uri, id )
end

.derivativeDirsObject

Returns the Array of directories to search for derivatives; part of the PluginFactory interface.



62
63
64
# File 'lib/arrow/session/lock.rb', line 62

def self::derivativeDirs
	[ 'arrow/session', 'arrow/session/lock' ]
end

Instance Method Details

#finishObject

Indicate to the lock that the caller will no longer be using it, and it may free any resources it had been using.



195
196
197
# File 'lib/arrow/session/lock.rb', line 195

def finish
	self.release_all_locks
end

#locked?Boolean

Returns true if the lock object currently holds either a read or write lock.

Returns:

  • (Boolean)


146
147
148
# File 'lib/arrow/session/lock.rb', line 146

def locked?
	(@status & (READ|WRITE)).nonzero?
end

#read_lock(blocking = true) ⇒ Object

Acquire a read (shared) lock. If blocking is false, will return false if the lock was not able to be acquired.



94
95
96
97
98
99
100
101
# File 'lib/arrow/session/lock.rb', line 94

def read_lock( blocking=true )
	return true if self.read_locked?
	self.log.debug "Acquiring read lock"
	self.acquire_read_lock( blocking ) or return false
	@status |= READ
	self.log.debug "Got read lock"
	return true
end

#read_locked?Boolean

Returns true if the lock object has acquired a read lock.

Returns:

  • (Boolean)


152
153
154
# File 'lib/arrow/session/lock.rb', line 152

def read_locked?
	(@status & READ).nonzero?
end

#read_unlockObject

Give up a read (shared) lock. Raises an exception if no read lock has been acquired.

Raises:

  • (Arrow::LockingError)


165
166
167
168
169
170
171
# File 'lib/arrow/session/lock.rb', line 165

def read_unlock
	raise Arrow::LockingError, "No read lock to release" unless
		self.read_locked?
	self.log.debug "Releasing read lock"
	self.release_read_lock
	@status &= ( @status ^ READ )
end

#release_all_locksObject

Release any locks acquired by this lock object.



186
187
188
189
190
# File 'lib/arrow/session/lock.rb', line 186

def release_all_locks
	return false unless self.locked?
	self.write_unlock if self.write_locked?
	self.read_unlock if self.read_locked?
end

#with_read_lock(blocking = true) ⇒ Object

Execute the given block after obtaining a read lock, and give up the lock when the block returns. If blocking is false, will raise an Errno::EAGAIN error without calling the block if the lock cannot be immediately established.



120
121
122
123
124
125
126
127
# File 'lib/arrow/session/lock.rb', line 120

def with_read_lock( blocking=true )
	begin
		self.read_lock( blocking ) or raise Errno::EAGAIN
		yield
	ensure
		self.release_read_lock
	end
end

#with_write_lock(blocking = true) ⇒ Object

Execute the given block after obtaining a write lock, and give up the lock when the block returns. If blocking is false, will raise an Errno::EAGAIN error without calling the block if the lock cannot be immediately established.



134
135
136
137
138
139
140
141
# File 'lib/arrow/session/lock.rb', line 134

def with_write_lock( blocking=true )
	begin
		self.write_lock( blocking ) or raise Errno::EAGAIN
		yield
	ensure
		self.release_write_lock
	end
end

#write_lock(blocking = true) ⇒ Object

Acquire a write (exclusive) lock. If blocking is false, will return false if the lock was not able to be acquired.



106
107
108
109
110
111
112
113
# File 'lib/arrow/session/lock.rb', line 106

def write_lock( blocking=true )
	return true if self.write_locked?
	self.log.debug "Acquiring write lock"
	self.acquire_write_lock( blocking ) or return false
	@status |= WRITE
	self.log.debug "Got write lock"
	return true
end

#write_locked?Boolean

Returns true if the lock object has acquired a write lock.

Returns:

  • (Boolean)


158
159
160
# File 'lib/arrow/session/lock.rb', line 158

def write_locked?
	(@status & WRITE).nonzero?
end

#write_unlockObject

Release a write (exclusive) lock. Raises an exception if no write lock has been acquired.

Raises:

  • (Arrow::LockingError)


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

def write_unlock
	raise Arrow::LockingError, "No write lock to release" unless
		self.write_locked?
	self.log.debug "Releasing write lock"
	self.release_write_lock
	@status &= ( @status ^ WRITE )
end