Interface ThreadContext
Example usage:
ThreadContext threadContext = ThreadContext.builder()
.propagated(ThreadContext.SECURITY, ThreadContext.APPLICATION)
.cleared(ThreadContext.TRANSACTION)
.unchanged(ThreadContext.ALL_REMAINING)
.build();
...
CompletableFuture<Integer> stage2 = stage1.thenApply(threadContext.contextualFunction(function));
...
Future<Integer> future = executor.submit(threadContext.contextualCallable(callable));
This interface is intentionally kept compatible with ContextService, with the hope that its methods might one day be contributed to that specification.
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringIdentifier for all available thread context types which are not specified individually undercleared,propagated, orunchanged.static final StringIdentifier for application context.static final StringIdentifier for CDI context.static final String[]An empty array of thread context.static final StringIdentifier for security context.static final StringIdentifier for transaction context. -
Method Summary
Modifier and TypeMethodDescriptionstatic ThreadContext.Builderbuilder()Creates a newThreadContext.Builderinstance.<R> Callable<R>contextualCallable(Callable<R> callable) Wraps aCallablewith context that is captured from the thread that invokescontextualCallable.<T,U> BiConsumer<T, U> contextualConsumer(BiConsumer<T, U> consumer) Wraps aBiConsumerwith context that is captured from the thread that invokescontextualConsumer.<T> Consumer<T>contextualConsumer(Consumer<T> consumer) Wraps aConsumerwith context that is captured from the thread that invokescontextualConsumer.<T,U, R> BiFunction<T, U, R> contextualFunction(BiFunction<T, U, R> function) Wraps aBiFunctionwith context that is captured from the thread that invokescontextualFunction.<T,R> Function<T, R> contextualFunction(Function<T, R> function) Wraps aFunctionwith context that is captured from the thread that invokescontextualFunction.contextualRunnable(Runnable runnable) Wraps aRunnablewith context that is captured from the thread that invokesContextualRunnable.<R> Supplier<R>contextualSupplier(Supplier<R> supplier) Wraps aSupplierwith context captured from the thread that invokescontextualSupplier.Creates anExecutorthat runs tasks on the same thread from whichexecuteis invoked but with context that is captured from the thread that invokescurrentContextExecutor.<T> CompletableFuture<T>withContextCapture(CompletableFuture<T> stage) Returns a newCompletableFuturethat is completed by the completion of the specified stage.<T> CompletionStage<T>withContextCapture(CompletionStage<T> stage) Returns a newCompletionStagethat is completed by the completion of the specified stage.
-
Field Details
-
ALL_REMAINING
Identifier for all available thread context types which are not specified individually under
cleared,propagated, orunchanged.When using this constant, be aware that bringing in a new context provider or updating levels of an existing context provider might change the set of available thread context types.
-
APPLICATION
Identifier for application context. Application context controls the application component that is associated with a thread. For Jakarta/Java EE applications, application context includes the thread context class loader as well as the java:comp, java:module, and java:app name spaces of the application. An empty/default application context means that the thread is not associated with any application. -
CDI
Identifier for CDI context. CDI context controls the availability of CDI scopes. An empty/default CDI context means that the thread does not have access to the scope of the session, request, and so forth that created the contextualized action. For example, consider the following@RequestScopedresource:
CDI context propagation includes request, session and conversation contexts. When CDI context is propagated, all of the above mentioned contexts that are currently active will be available to the contextualized task with preserved state.@RequestScoped public class MyRequestScopedBean { public String getState() { // returns some request-specific information to the caller } }
If CDI context is 'cleared', currently active contexts will still be available to the contextualized task, but their state will be erased. If CDI context is 'unchanged', access to CDI bean's contextual state will be non-deterministic. Namely, context may be missing, or context from a different task may be applied instead. This option is discouraged, and only should be used if CDI context is not used in an application.ManagedExecutor exec = ManagedExecutor.builder() .propagated(ThreadContext.CDI, ThreadContext.APPLICATION) .build(); @Inject MyRequestScopedBean requestBean; @GET public void foo() { exec.supplyAsync(() -> { String state = reqBean.getState(); // do some work with the request state }).thenApply(more -> { // request state also available in future stages }); } -
NONE
An empty array of thread context.
This is provided as a convenience for code that wishes to be more explicit. For example, you can specify
builder.propagated(ThreadContext.NONE)rather thanbuilder.propagated(new String[0])orbuilder.propagated(), all of which have the same meaning.When using MicroProfile Config to specify defaults, the value
Noneindicates an empty array. For example,mp.context.ThreadContext.unchanged=None
ormp.context.ManagedExecutor.propagated=None
-
SECURITY
Identifier for security context. Security context controls the credentials that are associated with the thread. An empty/default security context means that the thread is unauthenticated. -
TRANSACTION
Identifier for transaction context. Transaction context controls the active transaction scope that is associated with the thread. Implementations are not expected to propagate transaction context across threads. Instead, the concept of transaction context is provided for its cleared context, which means the active transaction on the thread is suspended such that a new transaction can be started if so desired. In most cases, the most desirable behavior will be to leave transaction context defaulted to cleared (suspended), in order to prevent dependent actions and tasks from accidentally enlisting in transactions that are on the threads where they happen to run.
-
-
Method Details
-
builder
Creates a newThreadContext.Builderinstance.- Returns:
- a new
ThreadContext.Builderinstance.
-
currentContextExecutor
Executor currentContextExecutor()Creates an
Executorthat runs tasks on the same thread from whichexecuteis invoked but with context that is captured from the thread that invokescurrentContextExecutor.Example usage:
Executor contextSnapshot = threadContext.currentContextExecutor(); ... // from another thread, or after thread context has changed, contextSnapshot.execute(() -> obj.doSomethingThatNeedsContext()); contextSnapshot.execute(() -> doSomethingElseThatNeedsContext(x, y));The returned
Executormust raiseIllegalArgumentExceptionif an already-contextualizedRunnableis supplied to itsexecutemethod.- Returns:
- an executor that wraps the
executemethod with context.
-
contextualCallable
Wraps a
Callablewith context that is captured from the thread that invokescontextualCallable.When
callis invoked on the proxy instance, context is first established on the thread that will run thecallmethod, then thecallmethod of the providedCallableis invoked. Finally, the previous context is restored on the thread, and the result of theCallableis returned to the invoker.- Type Parameters:
R- callable result type.- Parameters:
callable- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
callmethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedCallableis supplied to this method.
-
contextualConsumer
Wraps a
BiConsumerwith context that is captured from the thread that invokescontextualConsumer.When
acceptis invoked on the proxy instance, context is first established on the thread that will run theacceptmethod, then theacceptmethod of the providedBiConsumeris invoked. Finally, the previous context is restored on the thread, and control is returned to the invoker.- Type Parameters:
T- type of first parameter to consumer.U- type of second parameter to consumer.- Parameters:
consumer- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
acceptmethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedBiConsumeris supplied to this method.
-
contextualConsumer
Wraps a
Consumerwith context that is captured from the thread that invokescontextualConsumer.When
acceptis invoked on the proxy instance, context is first established on the thread that will run theacceptmethod, then theacceptmethod of the providedConsumeris invoked. Finally, the previous context is restored on the thread, and control is returned to the invoker.- Type Parameters:
T- type of parameter to consumer.- Parameters:
consumer- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
acceptmethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedConsumeris supplied to this method.
-
contextualFunction
Wraps a
BiFunctionwith context that is captured from the thread that invokescontextualFunction.When
applyis invoked on the proxy instance, context is first established on the thread that will run theapplymethod, then theapplymethod of the providedBiFunctionis invoked. Finally, the previous context is restored on the thread, and the result of theBiFunctionis returned to the invoker.- Type Parameters:
T- type of first parameter to function.U- type of second parameter to function.R- function result type.- Parameters:
function- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
applymethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedBiFunctionis supplied to this method.
-
contextualFunction
Wraps a
Functionwith context that is captured from the thread that invokescontextualFunction.When
applyis invoked on the proxy instance, context is first established on the thread that will run theapplymethod, then theapplymethod of the providedFunctionis invoked. Finally, the previous context is restored on the thread, and the result of theFunctionis returned to the invoker.- Type Parameters:
T- type of parameter to function.R- function result type.- Parameters:
function- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
applymethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedFunctionis supplied to this method.
-
contextualRunnable
Wraps a
Runnablewith context that is captured from the thread that invokesContextualRunnable.When
runis invoked on the proxy instance, context is first established on the thread that will run therunmethod, then therunmethod of the providedRunnableis invoked. Finally, the previous context is restored on the thread, and control is returned to the invoker.- Parameters:
runnable- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
runmethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedRunnableis supplied to this method.
-
contextualSupplier
Wraps a
Supplierwith context captured from the thread that invokescontextualSupplier.When
supplyis invoked on the proxy instance, context is first established on the thread that will run thesupplymethod, then thesupplymethod of the providedSupplieris invoked. Finally, the previous context is restored on the thread, and the result of theSupplieris returned to the invoker.- Type Parameters:
R- supplier result type.- Parameters:
supplier- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
supplymethod with context. - Throws:
IllegalArgumentException- if an already-contextualizedSupplieris supplied to this method.
-
withContextCapture
Returns a new
CompletableFuturethat is completed by the completion of the specified stage.The new completable future will use the same default executor as this ThreadContext, which can be a ManagedExecutor if this ThreadContext was obtained by
ManagedExecutor.getThreadContext()or the default executor service if provided by the platform (which can be done viaContextManager.Builder.withDefaultExecutorService(ExecutorService)), or otherwise have no default executor.If this thread context has no default executor, the new stage and all dependent stages created from it, and so forth, have no default asynchronous execution facility and must raise
UnsupportedOperationExceptionfor all*Asyncmethods that do not specify an executor. For example,thenRunAsync(Runnable).When dependent stages are created from the new completable future, thread context is captured and/or cleared as described in the documentation of the
ManagedExecutorclass, except that this ThreadContext instance takes the place of the default asynchronous execution facility in supplying the configuration of cleared/propagated context types. This guarantees that the action performed by each stage always runs under the thread context of the code that creates the stage, unless the user explicitly overrides by supplying a pre-contextualized action.Invocation of this method does not impact thread context propagation for the supplied completable future or any dependent stages created from it, other than the new dependent completable future that is created by this method.
- Type Parameters:
T- completable future result type.- Parameters:
stage- a completable future whose completion triggers completion of the new completable future that is created by this method.- Returns:
- the new completable future.
-
withContextCapture
Returns a new
CompletionStagethat is completed by the completion of the specified stage.The new completion stage will use the same default executor as this ThreadContext, which can be a ManagedExecutor if this ThreadContext was obtained by
ManagedExecutor.getThreadContext()or the default executor service if provided by the platform (which can be done viaContextManager.Builder.withDefaultExecutorService(ExecutorService)), or otherwise have no default executor.If this thread context has no default executor, the new stage and all dependent stages created from it, and so forth, have no default asynchronous execution facility and must raise
UnsupportedOperationExceptionfor all*Asyncmethods that do not specify an executor. For example,thenRunAsync(Runnable).When dependent stages are created from the new completion stage, thread context is captured and/or cleared as described in the documentation of the
ManagedExecutorclass, except that this ThreadContext instance takes the place of the default asynchronous execution facility in supplying the configuration of cleared/propagated context types. This guarantees that the action performed by each stage always runs under the thread context of the code that creates the stage, unless the user explicitly overrides by supplying a pre-contextualized action.Invocation of this method does not impact thread context propagation for the supplied stage or any dependent stages created from it, other than the new dependent completion stage that is created by this method.
- Type Parameters:
T- completion stage result type.- Parameters:
stage- a completion stage whose completion triggers completion of the new stage that is created by this method.- Returns:
- the new completion stage.
-