UNPKG

diffusion

Version:

Diffusion JavaScript client

129 lines (122 loc) 5.05 kB
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 &ndash; 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' ]);