@API(value=EXPERIMENTAL) public class SynchronizedSessionRunner extends Object implements FDBDatabaseRunner
FDBDatabaseRunner
implementation that performs all work in the context of a
SynchronizedSession
.
For all variations of run
and runAsync
methods, the work in the retriable
lambda
is wrapped by calls that check locks and update leases to ensure that two synchronized sessions are not
concurrently running at the same time.
SynchronizedSession
FDBDatabaseRunner.RunnerClosed
Modifier and Type | Method and Description |
---|---|
<T> T |
asyncToSync(StoreTimer.Wait event,
CompletableFuture<T> async) |
void |
close()
Close this runner.
|
void |
endAnySession()
Synchronous/blocking version of
endAnySessionAsync() . |
CompletableFuture<Void> |
endAnySessionAsync()
Releases the lock to end any synchronized session on the same lock subspace, no matter whether the current
session holds the lock or not.
|
void |
endSession()
Synchronous/blocking version of
endSessionAsync() . |
CompletableFuture<Void> |
endSessionAsync()
Releases the lock to end the synchronized session.
|
FDBDatabase |
getDatabase()
Get the database against which functions are run.
|
Executor |
getExecutor()
|
long |
getInitialDelayMillis()
Gets the delay ceiling (in milliseconds) that will be applied between attempts to
run a transactional database operation.
|
int |
getMaxAttempts()
Gets the maximum number of attempts for a database to make when running a
retriable transactional operation.
|
long |
getMaxDelayMillis()
Gets the maximum delay (in milliseconds) that will be applied between attempts to
run a transactional database operation.
|
Map<String,String> |
getMdcContext()
Get the logging context used in record contexts opened by this runner.
|
long |
getMinDelayMillis()
Gets the minimum delay (in milliseconds) that will be applied between attempts to
run a transactional database operation.
|
FDBTransactionPriority |
getPriority()
Get the priority of transactions opened by this runner.
|
UUID |
getSessionId() |
FDBStoreTimer |
getTimer()
Get the timer used in record contexts opened by this runner.
|
long |
getTransactionTimeoutMillis()
Get the transaction timeout for all transactions started by this runner.
|
FDBDatabase.WeakReadSemantics |
getWeakReadSemantics()
Get the read semantics used in record contexts opened by this runner.
|
static SynchronizedSessionRunner |
joinSession(Subspace lockSubspace,
UUID sessionId,
long leaseLengthMill,
FDBDatabaseRunnerImpl runner)
Produces a new runner, wrapping a given runner, which performs all work in the context of an existing
SynchronizedSession . |
SynchronizedSessionRunner |
joinSynchronizedSession(Subspace lockSubspace,
UUID sessionId,
long leaseLengthMillis)
Produces a new runner, wrapping this runner, which performs all work in the context of an existing
SynchronizedSession . |
FDBRecordContext |
openContext()
Open a new record context.
|
<T> T |
run(Function<? super FDBRecordContext,? extends T> retriable,
List<Object> additionalLogMessageKeyValues)
Runs a transactional function against with retry logic.
|
<T> CompletableFuture<T> |
runAsync(Function<? super FDBRecordContext,CompletableFuture<? extends T>> retriable,
BiFunction<? super T,Throwable,? extends org.apache.commons.lang3.tuple.Pair<? extends T,? extends Throwable>> handlePostTransaction,
List<Object> additionalLogMessageKeyValues)
Runs a transactional function asynchronously with retry logic.
|
void |
setInitialDelayMillis(long initialDelayMillis)
Sets the delay ceiling (in milliseconds) that will be applied between attempts to
run a transactional database operation.
|
void |
setMaxAttempts(int maxAttempts)
Sets the maximum number of attempts for a database to make when running a
retriable transactional operation.
|
void |
setMaxDelayMillis(long maxDelayMillis)
Sets the maximum delay (in milliseconds) that will be applied between attempts to
run a transactional database operation.
|
void |
setMdcContext(Map<String,String> mdcContext)
Set the logging context used in record contexts opened by this runner.
|
void |
setPriority(FDBTransactionPriority priority)
Set the priority of transactions opened by this runner.
|
void |
setTimer(FDBStoreTimer timer)
Set the timer used in record contexts opened by this runner.
|
void |
setTransactionTimeoutMillis(long transactionTimeoutMillis)
Set the transaction timeout for all transactions started by this runner.
|
void |
setWeakReadSemantics(FDBDatabase.WeakReadSemantics weakReadSemantics)
Set the read semantics used in record contexts opened by this runner.
|
static SynchronizedSessionRunner |
startSession(Subspace lockSubspace,
long leaseLengthMill,
FDBDatabaseRunnerImpl runner)
Synchronous/blocking version of
startSessionAsync(Subspace, long, FDBDatabaseRunnerImpl) . |
static CompletableFuture<SynchronizedSessionRunner> |
startSessionAsync(Subspace lockSubspace,
long leaseLengthMill,
FDBDatabaseRunnerImpl runner)
Produces a new runner, wrapping a given runner, which performs all work in the context of a new
SynchronizedSession . |
SynchronizedSessionRunner |
startSynchronizedSession(Subspace lockSubspace,
long leaseLengthMillis)
Synchronous/blocking version of
FDBDatabaseRunner.startSynchronizedSessionAsync(Subspace, long) . |
CompletableFuture<SynchronizedSessionRunner> |
startSynchronizedSessionAsync(Subspace lockSubspace,
long leaseLengthMillis)
Produces a new runner, wrapping this runner, which performs all work in the context of a new
SynchronizedSession . |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
run, runAsync, runAsync
public static CompletableFuture<SynchronizedSessionRunner> startSessionAsync(@Nonnull Subspace lockSubspace, long leaseLengthMill, @Nonnull FDBDatabaseRunnerImpl runner)
SynchronizedSession
.
The returned runner will have acquired and started the lease, so care must be taken to ensure that work begins before the lease expiration period.
lockSubspace
- the lock for which the session contendsleaseLengthMill
- length between last access and lease's end time in millisecondsrunner
- the underlying runnerpublic static SynchronizedSessionRunner startSession(@Nonnull Subspace lockSubspace, long leaseLengthMill, @Nonnull FDBDatabaseRunnerImpl runner)
startSessionAsync(Subspace, long, FDBDatabaseRunnerImpl)
.lockSubspace
- the lock for which the session contendsleaseLengthMill
- length between last access and lease's end time in millisecondsrunner
- the underlying runnerpublic static SynchronizedSessionRunner joinSession(@Nonnull Subspace lockSubspace, @Nonnull UUID sessionId, long leaseLengthMill, @Nonnull FDBDatabaseRunnerImpl runner)
SynchronizedSession
.lockSubspace
- the lock for which the session contendssessionId
- session IDleaseLengthMill
- length between last access and lease's end time in millisecondsrunner
- the underlying runnerpublic UUID getSessionId()
public CompletableFuture<Void> endSessionAsync()
null
when the session is endedpublic void endSession()
endSessionAsync()
.public CompletableFuture<Void> endAnySessionAsync()
null
when the session is endedSynchronizedSession.endAnySession(Transaction, Subspace)
public void endAnySession()
endAnySessionAsync()
.public <T> T run(@Nonnull Function<? super FDBRecordContext,? extends T> retriable, @Nullable List<Object> additionalLogMessageKeyValues)
FDBDatabaseRunner
FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
for the non-blocking version of this method.run
in interface FDBDatabaseRunner
T
- return type of function to runretriable
- the database operation to run transactionallyadditionalLogMessageKeyValues
- additional key/value pairs to be included in logsFDBDatabaseRunner.runAsync(Function)
@Nonnull public <T> CompletableFuture<T> runAsync(@Nonnull Function<? super FDBRecordContext,CompletableFuture<? extends T>> retriable, @Nonnull BiFunction<? super T,Throwable,? extends org.apache.commons.lang3.tuple.Pair<? extends T,? extends Throwable>> handlePostTransaction, @Nullable List<Object> additionalLogMessageKeyValues)
FDBDatabaseRunner
runAsync
in interface FDBDatabaseRunner
T
- return type of function to runretriable
- the database operation to run transactionallyhandlePostTransaction
- after the transaction is committed, or fails to commit, this function is called with the
result or exception respectively. This handler should return a new pair with either the result to return from
runAsync
or an exception to be checked whether retriable
should be retried.additionalLogMessageKeyValues
- additional key/value pairs to be included in logsretriable
after successful run and commitFDBDatabaseRunner.run(Function)
@Nonnull public FDBDatabase getDatabase()
FDBDatabaseRunner
getDatabase
in interface FDBDatabaseRunner
public Executor getExecutor()
FDBDatabaseRunner
FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
.getExecutor
in interface FDBDatabaseRunner
@Nullable public FDBStoreTimer getTimer()
FDBDatabaseRunner
getTimer
in interface FDBDatabaseRunner
public void setTimer(@Nullable FDBStoreTimer timer)
FDBDatabaseRunner
setTimer
in interface FDBDatabaseRunner
timer
- timer to useFDBDatabase.openContext(Map,FDBStoreTimer)
@Nullable public Map<String,String> getMdcContext()
FDBDatabaseRunner
getMdcContext
in interface FDBDatabaseRunner
public void setMdcContext(@Nullable Map<String,String> mdcContext)
FDBDatabaseRunner
mdcContext
.setMdcContext
in interface FDBDatabaseRunner
mdcContext
- the logging context to useFDBDatabase.openContext(Map,FDBStoreTimer)
@Nullable public FDBDatabase.WeakReadSemantics getWeakReadSemantics()
FDBDatabaseRunner
getWeakReadSemantics
in interface FDBDatabaseRunner
public void setWeakReadSemantics(@Nullable FDBDatabase.WeakReadSemantics weakReadSemantics)
FDBDatabaseRunner
FDBDatabaseRunner.run(Function)
, FDBDatabaseRunner.runAsync(Function)
, and their variants, only the first
context (from the first iteration round the loop) actually sets the created record context's
FDBDatabase.WeakReadSemantics
to the provided value. This is because there are several
reasons why a transaction may fail due to a stale read version (for example, a
conflict
or expired transaction),
and subsequent attempts will fail if their read version is not updated to a newer value.setWeakReadSemantics
in interface FDBDatabaseRunner
weakReadSemantics
- allowable staleness parameters if caching read versionsFDBDatabase.openContext(Map,FDBStoreTimer,FDBDatabase.WeakReadSemantics)
@Nonnull public FDBTransactionPriority getPriority()
FDBDatabaseRunner
getPriority
in interface FDBDatabaseRunner
FDBRecordContext.getPriority()
public void setPriority(@Nonnull FDBTransactionPriority priority)
FDBDatabaseRunner
setPriority
in interface FDBDatabaseRunner
priority
- the priority of transactions by this runnerFDBRecordContext.getPriority()
public int getMaxAttempts()
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to limit the number of
attempts that an operation is retried.getMaxAttempts
in interface FDBDatabaseRunner
public void setMaxAttempts(int maxAttempts)
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to limit the number of
attempts that an operation is retried.setMaxAttempts
in interface FDBDatabaseRunner
maxAttempts
- the maximum number of times to run a transactional database operationpublic long getMinDelayMillis()
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to limit the time spent
between successive attempts at completing a database operation.
Currently this value is fixed at 2 milliseconds and is not settable.getMinDelayMillis
in interface FDBDatabaseRunner
public long getMaxDelayMillis()
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to limit the time spent
between successive attempts at completing a database operation. The default value is 1000 so that
there will not be more than 1 second between attempts.getMaxDelayMillis
in interface FDBDatabaseRunner
public void setMaxDelayMillis(long maxDelayMillis)
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to limit the time spent
between successive attempts at completing a database operation. The default value is 1000 so that
there will not be more than 1 second between attempts.setMaxDelayMillis
in interface FDBDatabaseRunner
maxDelayMillis
- the maximum delay between attempts when retrying operationspublic long getInitialDelayMillis()
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to determine how
long to wait between the first and second attempts at running a database operation.
The exponential backoff algorithm will choose an amount of time to wait between zero
and the initial delay, and will use that value each successive iteration to determine
how long that wait should be. The default value is 10 milliseconds.getInitialDelayMillis
in interface FDBDatabaseRunner
public void setInitialDelayMillis(long initialDelayMillis)
FDBDatabaseRunner
FDBDatabaseRunner.run(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, ? extends T>)
and FDBDatabaseRunner.runAsync(java.util.function.Function<? super com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext, java.util.concurrent.CompletableFuture<? extends T>>)
to determine how
long to wait between the first and second attempts at running a database operation.
The exponential backoff algorithm will choose an amount of time to wait between zero
and the initial delay, and will use that value each successive iteration to determine
how long that wait should be. The default value is 10 milliseconds.setInitialDelayMillis
in interface FDBDatabaseRunner
initialDelayMillis
- the delay ceiling between the first and second attempts at running a database operationpublic void setTransactionTimeoutMillis(long transactionTimeoutMillis)
FDBDatabaseRunner
FDBDatabaseFactory.DEFAULT_TR_TIMEOUT_MILLIS
,
then this will use the value of set in the originating database's factory. If set to FDBDatabaseFactory.UNLIMITED_TR_TIMEOUT_MILLIS
,
then no timeout will be imposed on transactions used by this runner.
Note that the error that the transaction hits, FDBExceptions.FDBStoreTransactionTimeoutException
,
is not retriable, so if the runner encounters such an error, it will terminate.
setTransactionTimeoutMillis
in interface FDBDatabaseRunner
transactionTimeoutMillis
- the transaction timeout time in millisecondsFDBDatabaseFactory.setTransactionTimeoutMillis(long)
public long getTransactionTimeoutMillis()
FDBDatabaseRunner
FDBDatabaseRunner.setTransactionTimeoutMillis(long)
. Note, however, that if the transaction timeout
is set to FDBDatabaseFactory.DEFAULT_TR_TIMEOUT_MILLIS
, then the actual timeout set for this transaction
will be set to the value in the originating factory.getTransactionTimeoutMillis
in interface FDBDatabaseRunner
FDBDatabaseRunner.setTransactionTimeoutMillis(long)
@Nonnull public FDBRecordContext openContext()
FDBDatabaseRunner
openContext
in interface FDBDatabaseRunner
FDBDatabase.openContext(Map,FDBStoreTimer,FDBDatabase.WeakReadSemantics)
@Nullable public <T> T asyncToSync(StoreTimer.Wait event, @Nonnull CompletableFuture<T> async)
asyncToSync
in interface FDBDatabaseRunner
public void close()
FDBDatabaseRunner
runAsync
close
in interface FDBDatabaseRunner
close
in interface AutoCloseable
public CompletableFuture<SynchronizedSessionRunner> startSynchronizedSessionAsync(@Nonnull Subspace lockSubspace, long leaseLengthMillis)
FDBDatabaseRunner
SynchronizedSession
.
The returned runner will have acquired and started the lease, so care must be taken to ensure that work begins before the lease expiration period.
startSynchronizedSessionAsync
in interface FDBDatabaseRunner
lockSubspace
- the lock for which the session contendsleaseLengthMillis
- length between last access and lease's end time in millisecondsSynchronizedSession
public SynchronizedSessionRunner startSynchronizedSession(@Nonnull Subspace lockSubspace, long leaseLengthMillis)
FDBDatabaseRunner
FDBDatabaseRunner.startSynchronizedSessionAsync(Subspace, long)
.startSynchronizedSession
in interface FDBDatabaseRunner
lockSubspace
- the lock for which the session contendsleaseLengthMillis
- length between last access and lease's end time in millisecondspublic SynchronizedSessionRunner joinSynchronizedSession(@Nonnull Subspace lockSubspace, @Nonnull UUID sessionId, long leaseLengthMillis)
FDBDatabaseRunner
SynchronizedSession
.joinSynchronizedSession
in interface FDBDatabaseRunner
lockSubspace
- the lock for which the session contendssessionId
- session IDleaseLengthMillis
- length between last access and lease's end time in millisecondsSynchronizedSession