Interface ISessionLock

A ISession lock.

Namespace: PushTechnology.ClientInterface.Client.Session
Assembly: Diffusion.Client.dll
Syntax
public interface ISessionLock
Remarks

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.

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.

A session lock is acquired using the LockAsync(String) 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 LockAsync(String) more than once for a given session lock – if the lock is acquired, all calls will complete successfully with equal ISessionLock values.

If a session closes, the session locks it owns are automatically released. A session can also release a lock by calling UnlockAsync(). 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 LockAsync(String) calls will complete normally. Other sessions will continue to wait.

The LockAsync(String, SessionLockScope) variant of this method takes a scope parameter that provides the further option of automatically releasing the lock when the session loses its connection to the server.


Race conditions

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

  • Due to the check-then-act approach of polling IsOwned, the lock can be lost after the check has succeeded but before the resource is accessed;
  • The server can detect a session is disconnected and assign the lock to another session before the original session has detected the disconnection.

Despite this imprecision, session locks provide a useful way to coordinate session actions.


Note

This interface does not require user implementation and is only used to hide implementation details.

Added in 6.2.

Examples

Acquiring a session lock.

// session is a previously obtained ISession instance.
var sessionLock = await session.LockAsync( "lock name" );

Properties

IsOwned

Gets whether this session lock is still owned.

Declaration
bool IsOwned { get; }
Property Value
Type Description
System.Boolean

true if this session lock is still owned by the session. Otherwise false.

Remarks

Added in 6.2.

Examples

Checking if a session lock is still owned by the session.

// session is a previously obtained ISession instance.
var sessionLock = await session.LockAsync( "lock name" );

// ...

if ( sessionLock.IsOwned ) {
    Console.WriteLine( "Session lock is still owned by the session." );
} else {
    Console.WriteLine( "Session lock is still owned by the session." );
}

Name

Gets the name of this session lock.

Declaration
string Name { get; }
Property Value
Type Description
System.String

The name of this session lock.

Remarks

Added in 6.2.

Examples

Printing the name of a session lock to the terminal.

// session is a previously obtained ISession instance.
var sessionLock = await session.LockAsync( "lock name" );
Console.WriteLine( sessionLock.Name ); // Prints "lock name"

Scope

Gets the scope of this session lock.

Declaration
SessionLockScope Scope { get; }
Property Value
Type Description
SessionLockScope

The scope of this session lock.

Remarks

The scope determines when the lock will be released automatically.

If a session makes multiple 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.


Added in 6.2.

Examples

Printing the scope of a session lock to the terminal.

// session is a previously obtained ISession instance.
var sessionLock = await session.LockAsync( "lock name" );
Console.WriteLine( sessionLock.Scope );
See Also
LockAsync(String, SessionLockScope)

Sequence

Gets the sequence number of this session lock.

Declaration
long Sequence { get; }
Property Value
Type Description
System.Int64

The sequence number.

Remarks

This is a value identifying the acquisition of the lock with the given Name. Session locks that are acquired later are guaranteed to have bigger sequence values, allowing the sequence number to be used as a fencing token.


Added in 6.2.

Examples

Printing the sequence number of a session lock to the terminal.

// session is a previously obtained ISession instance.
var sessionLock = await session.LockAsync( "lock name" );
Console.WriteLine( sessionLock.Sequence );

Methods

UnlockAsync()

Releases this session lock if it is owned by the session.

Declaration
Task<bool> UnlockAsync()
Returns
Type Description
Task<System.Boolean>

The Task representing the current operation.

Remarks

If the operation completes successfully, the Task result will be a bool value and the calling session will no longer own the named session lock. A result of true indicates the calling session previously owned the lock and false indicates it did not.

This method is the same as calling UnlockAsync(CancellationToken) with System.Threading.CancellationToken.None.


Added in 6.2.

Examples

Unlocking a previously obtained session lock.

// sessionLock is a previously obtained ISessionLock instance.
try {
    var owned = await sessionLock.UnlockAsync();
    if ( owned ) {
        Console.WriteLine( "Previously owned session lock released." );
    } else {
        Console.WriteLine( "Session lock was not owned by the current session." );
    }
} catch (SessionClosedException ex ) {
    Console.WriteLine( "Couldn't release session lock because the session was closed." );
}
Exceptions
Type Condition
SessionClosedException

The calling session is closed. Thrown by the returned Task.

See Also
UnlockAsync(CancellationToken)
LockAsync(String)

UnlockAsync(CancellationToken)

Releases this session lock if it is owned by the session.

Declaration
Task<bool> UnlockAsync(CancellationToken cancellationToken)
Parameters
Type Name Description
CancellationToken cancellationToken

The cancellation token used to cancel the current operation.

Returns
Type Description
Task<System.Boolean>

The Task representing the current operation.

Remarks

If the operation completes successfully, the Task result will be a bool value and the calling session will no longer own the named session lock. A result of true indicates the calling session previously owned the lock and false indicates it did not.


Added in 6.2.

Examples

Unlocking a previously obtained session lock.

// sessionLock is a previously obtained ISessionLock instance.
var cancellationTokenSource = new CancellationTokenSource();
try {
    var owned = await sessionLock.UnlockAsync( cancellationTokenSource.Token );
    if ( owned ) {
        Console.WriteLine( "Previously owned session lock released." );
    } else {
        Console.WriteLine( "Session lock was not owned by the current session." );
    }
} catch (SessionClosedException ex ) {
    Console.WriteLine( "Couldn't release session lock because the session was closed." );
}
Exceptions
Type Condition
SessionClosedException

The calling session is closed. Thrown by the returned Task.

See Also
LockAsync(String, CancellationToken)
Back to top