diffusion
Version:
Diffusion JavaScript client
129 lines (122 loc) • 5.05 kB
JavaScript
var _interface = require('util/interface')._interface;
/**
* A session lock is a server-managed resource that can be used to
* coordinate exclusive access to shared resources across sessions. For
* example, to ensure a single session has the right to update a topic; to
* ensure at most one session responds to an event; or to select a single
* session to perform a housekeeping task. Session locks support general
* collaborative locking schemes. The application architect is responsible
* for designing a suitable locking scheme and for ensuring each application
* component follows the scheme appropriately.
*
* <P>
* Session locks are identified by a lock name. Lock names are arbitrary and
* chosen at will to suit the application. Each lock is owned by at most one
* session. Locks are established on demand; there is no separate operation
* to create or destroy a lock.
*
* <P>
* A session lock is acquired using the {@link Session#lock} method.
* If no other session owns the lock, the server will assign the lock to the
* calling session immediately. Otherwise, the server will record that the
* session is waiting to acquire the lock. A session can call <code>lock</code>
* more than once for a given session lock – if the lock is acquired,
* all calls will complete successfully with equal SessionLocks.
*
* <P>
* If a session closes, the session locks it owns are automatically
* released. A session can also {@link SessionLock#unlock release a lock}.
* When a session lock is released and other sessions are waiting to acquire
* the lock, the server will arbitrarily select one of the waiting sessions
* and notify it that it has acquired the lock. All of the newly selected
* session's pending <code>lock</code> calls will complete normally. Other
* sessions will continue to wait.
*
* <P>
* The {@link Session#lock} method takes an optional scope parameter that
* provides the further option of automatically releasing the lock when the
* session loses its connection to the server.
*
* <h3>Race conditions</h3>
* <P>
* This session lock API has inherent race conditions. Even if an
* application is coded correctly to protect a shared resource using session
* locks, there may be a period where two or more sessions concurrently
* access the resource. The races arise for several reasons including
* <ul>
* <li>due to the <em>check-then-act</em> approach of polling
* {@link #isOwned}, the lock can be lost after the check has succeeded but
* before the resource is accessed;
* <li>the server can detect a session is disconnected and assign the lock
* to another session before the original session has detected the
* disconnection.
* </ul>
* <P>
* Despite this imprecision, session locks provide a useful way to
* coordinate session actions.
*
* @class SessionLock
*/
module.exports.SessionLock = _interface('SessionLock', [
/**
* @function SessionLock#getName
* @return {String} the name of the session lock
*/
'getName',
/**
* A value that identifies the acquisition of the lock with the
* given {@link #getName name}. SessionLocks that are acquired
* later are guaranteed to have bigger sequence values, allowing the
* sequence number to be used as a fencing token.
*
* @function SessionLock#getSequence
* @return {Number} a value that identifies the acquisition of this lock
*/
'getSequence',
/**
* Test whether the session lock is still owned.
*
* @function SessionLock#isOwned
* @return {Boolean} true if the session lock is still owned by the session
*/
'isOwned',
/**
* The scope of the lock.
*
* <P>
* The scope determines when the lock will be released automatically.
*
* <P>
* If a session makes multiple
* {@link Session#lock requests for a lock}
* using different scopes, and the server assigns the lock to the session
* fulfilling the requests, the lock will be given the weakest scope
* (UNLOCK_ON_CONNECTION_LOSS). Consequently, an individual request can
* complete with a lock that has a different scope to that requested.
*
* @function SessionLock#getScope
* @return {diffusion.locks.SessionLockScope} the lock scope
* @see Session#lock
*/
'getScope',
/**
* Release a session lock, if owned.
*
* @function SessionLock#unlock
* @return a Promise that resolves when a response is received
* from the server.
*
* <P>
* On completion, this session will no longer own the named session
* lock. If Promise completes normally, a true value indicates this
* session previously owned the lock and a false value indicates
* it did not.
*
* <P>
* If the Promise resolves with an error, this session
* does not own the session lock.
*
* @see Session#lock(String)
*/
'unlock'
]);