Class SynchronizedSession
- java.lang.Object
-
- com.apple.foundationdb.synchronizedsession.SynchronizedSession
-
@API(EXPERIMENTAL) public class SynchronizedSession extends Object
ASynchronizedSession
is a concept introduced to avoid multiple attempts at performing the same operation (with each attempt opening multiple transactions running concurrently and/or consecutively) from running concurrently and contending for resources. Each attempt corresponds to a session identified by a session ID. Of the sessions with the same lock subspace, only the one holding the lock is allowed to work.Each session should and should only try to acquire the lock when the session is initialized.
When a session holds the lock, it is protected from other sessions grabbing the same lock for an extended length of time (a.k.a lease). Another new session can only take lock if the lease of the original lock owner is outdated. (Note a session is allowed to work even if its lease is outdated, as long as no other session takes its lock.) In order to keep the lease, every time a session is used, it needs to update the lease's end time to some time (configured by
leaseLengthMillis
) later than current time. (The lease time is used only as an optimization.SynchronizedSession
does not depend on synchronized clocks for the correctness of mutual exclusion.)If a session is not able to acquire the lock during the initialization or loses the lock later, it will get a
SynchronizedSessionLockedException
. The session is considered ended when it gets a such exception. It can neither try to acquire the lock again nor commit any work.initializeSessionAsync(com.apple.foundationdb.Transaction)
should be used when initializing a session to acquire the lock, whilecheckLockAsync(Transaction)
andupdateLockSessionLeaseEndTime(Transaction)
should be used in every other transactions to check the lock and keep the lease. Please refer toSynchronizedSessionRunner
infdb-record-layer-core
for an example of usingSynchronizedSession
in practice.
-
-
Constructor Summary
Constructors Constructor Description SynchronizedSession(Subspace lockSubspace, UUID sessionId, long leaseLengthMillis)
Construct a session.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static CompletableFuture<Boolean>
checkActiveSessionExists(Transaction tr, Subspace lockSubspace)
Check if there is any active session on the given lock subspace, so that a new session would not able to be initialized.CompletableFuture<Void>
checkLockAsync(Transaction tr)
Check if the session still holds the lock.void
endAnySession(Transaction tr)
End any active session on the lock subspace by releasing the lock no matter whether this session holds the lock or not.static void
endAnySession(Transaction tr, Subspace lockSubspace)
End any active session on the given lock subspace by releasing the lock.UUID
getSessionId()
Get session ID.CompletableFuture<Void>
initializeSessionAsync(Transaction tr)
Initialize the session by acquiring the lock.CompletableFuture<Void>
releaseLock(Transaction tr)
End the session by releasing the lock if it still holds the lock.void
updateLockSessionLeaseEndTime(Transaction tr)
Update the lease's end time.
-
-
-
Constructor Detail
-
SynchronizedSession
public SynchronizedSession(@Nonnull Subspace lockSubspace, @Nonnull UUID sessionId, long leaseLengthMillis)
Construct a session. Remember to callinitializeSessionAsync(Transaction)
if thesessionId
is newly generated.- Parameters:
lockSubspace
- the lock for which this session contendssessionId
- session IDleaseLengthMillis
- length between last access and lease's end time in milliseconds
-
-
Method Detail
-
initializeSessionAsync
public CompletableFuture<Void> initializeSessionAsync(@Nonnull Transaction tr)
Initialize the session by acquiring the lock. This should be invoked before a new session is ever used.- Parameters:
tr
- transaction to use- Returns:
- a future that will return
null
when the session is initialized
-
checkLockAsync
public CompletableFuture<Void> checkLockAsync(@Nonnull Transaction tr)
Check if the session still holds the lock. This should be invoked in every transaction in the session to follow the contract.- Parameters:
tr
- transaction to use- Returns:
- a future that will return
null
when the lock is checked
-
releaseLock
public CompletableFuture<Void> releaseLock(@Nonnull Transaction tr)
End the session by releasing the lock if it still holds the lock. Do nothing otherwise.- Parameters:
tr
- transaction to use- Returns:
- a future that will return
null
when the lock is no longer this session
-
endAnySession
public void endAnySession(@Nonnull Transaction tr)
End any active session on the lock subspace by releasing the lock no matter whether this session holds the lock or not.It only takes place when the given transaction is committed. It will only be enforced when the other processes holding the lock go to check the lease in later transactions, where they will fail with
SynchronizedSessionLockedException
.- Parameters:
tr
- transaction to use
-
endAnySession
public static void endAnySession(@Nonnull Transaction tr, @Nonnull Subspace lockSubspace)
End any active session on the given lock subspace by releasing the lock.It only takes place when the given transaction is committed. It will only be enforced when the other processes holding the lock go to check the lease in later transactions, where they will fail with
SynchronizedSessionLockedException
.- Parameters:
tr
- transaction to uselockSubspace
- the lock whose active session needs to be ended
-
checkActiveSessionExists
public static CompletableFuture<Boolean> checkActiveSessionExists(@Nonnull Transaction tr, @Nonnull Subspace lockSubspace)
Check if there is any active session on the given lock subspace, so that a new session would not able to be initialized.- Parameters:
tr
- transaction to uselockSubspace
- the lock whose active session needs to be checked- Returns:
true
if there is any active session, otherwisefalse
-
updateLockSessionLeaseEndTime
public void updateLockSessionLeaseEndTime(@Nonnull Transaction tr)
Update the lease's end time. This should be invoked in every transaction in the session to keep the session alive.- Parameters:
tr
- transaction to use
-
-