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
-
Field Summary
Modifier and TypeFieldDescriptionstatic final String
Identifier for all available thread context types which are not specified individually undercleared
,propagated
, orunchanged
.static final String
Identifier for application context.static final String
Identifier for CDI context.static final String[]
An empty array of thread context.static final String
Identifier for security context.static final String
Identifier for transaction context. -
Method Summary
Modifier and TypeMethodDescriptionstatic ThreadContext.Builder
builder()
Creates a newThreadContext.Builder
instance.<R> Callable<R>
contextualCallable
(Callable<R> callable) Wraps aCallable
with context that is captured from the thread that invokescontextualCallable
.<T,
U> BiConsumer<T, U> contextualConsumer
(BiConsumer<T, U> consumer) Wraps aBiConsumer
with context that is captured from the thread that invokescontextualConsumer
.<T> Consumer<T>
contextualConsumer
(Consumer<T> consumer) Wraps aConsumer
with context that is captured from the thread that invokescontextualConsumer
.<T,
U, R> BiFunction<T, U, R> contextualFunction
(BiFunction<T, U, R> function) Wraps aBiFunction
with context that is captured from the thread that invokescontextualFunction
.<T,
R> Function<T, R> contextualFunction
(Function<T, R> function) Wraps aFunction
with context that is captured from the thread that invokescontextualFunction
.contextualRunnable
(Runnable runnable) Wraps aRunnable
with context that is captured from the thread that invokesContextualRunnable
.<R> Supplier<R>
contextualSupplier
(Supplier<R> supplier) Wraps aSupplier
with context captured from the thread that invokescontextualSupplier
.Creates anExecutor
that runs tasks on the same thread from whichexecute
is invoked but with context that is captured from the thread that invokescurrentContextExecutor
.<T> CompletableFuture<T>
withContextCapture
(CompletableFuture<T> stage) Returns a newCompletableFuture
that is completed by the completion of the specified stage.<T> CompletionStage<T>
withContextCapture
(CompletionStage<T> stage) Returns a newCompletionStage
that 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. It can determine the thread context class loader as well as the set of resource references that are available for lookup or resource injection. 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@RequestScoped
resource:
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 specifybuilder.propagated(ThreadContext.NONE)
rather thanbuilder.propagated(new String[0])
orbuilder.propagated()
, all of which have the same meaning. -
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.Builder
instance.- Returns:
- a new
ThreadContext.Builder
instance.
-
currentContextExecutor
Executor currentContextExecutor()Creates an
Executor
that runs tasks on the same thread from whichexecute
is 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
Executor
must raiseIllegalArgumentException
if an already-contextualizedRunnable
is supplied to itsexecute
method.- Returns:
- an executor that wraps the
execute
method with context.
-
contextualCallable
Wraps a
Callable
with context that is captured from the thread that invokescontextualCallable
.When
call
is invoked on the proxy instance, context is first established on the thread that will run thecall
method, then thecall
method of the providedCallable
is invoked. Finally, the previous context is restored on the thread, and the result of theCallable
is returned to the invoker.- Type Parameters:
R
- callable result type.- Parameters:
callable
- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
call
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedCallable
is supplied to this method.
-
contextualConsumer
Wraps a
BiConsumer
with context that is captured from the thread that invokescontextualConsumer
.When
accept
is invoked on the proxy instance, context is first established on the thread that will run theaccept
method, then theaccept
method of the providedBiConsumer
is 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
accept
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedBiConsumer
is supplied to this method.
-
contextualConsumer
Wraps a
Consumer
with context that is captured from the thread that invokescontextualConsumer
.When
accept
is invoked on the proxy instance, context is first established on the thread that will run theaccept
method, then theaccept
method of the providedConsumer
is 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
accept
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedConsumer
is supplied to this method.
-
contextualFunction
Wraps a
BiFunction
with context that is captured from the thread that invokescontextualFunction
.When
apply
is invoked on the proxy instance, context is first established on the thread that will run theapply
method, then theapply
method of the providedBiFunction
is invoked. Finally, the previous context is restored on the thread, and the result of theBiFunction
is 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
apply
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedBiFunction
is supplied to this method.
-
contextualFunction
Wraps a
Function
with context that is captured from the thread that invokescontextualFunction
.When
apply
is invoked on the proxy instance, context is first established on the thread that will run theapply
method, then theapply
method of the providedFunction
is invoked. Finally, the previous context is restored on the thread, and the result of theFunction
is 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
apply
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedFunction
is supplied to this method.
-
contextualRunnable
Wraps a
Runnable
with context that is captured from the thread that invokesContextualRunnable
.When
run
is invoked on the proxy instance, context is first established on the thread that will run therun
method, then therun
method of the providedRunnable
is 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
run
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedRunnable
is supplied to this method.
-
contextualSupplier
Wraps a
Supplier
with context captured from the thread that invokescontextualSupplier
.When
supply
is invoked on the proxy instance, context is first established on the thread that will run thesupply
method, then thesupply
method of the providedSupplier
is invoked. Finally, the previous context is restored on the thread, and the result of theSupplier
is returned to the invoker.- Type Parameters:
R
- supplier result type.- Parameters:
supplier
- instance to contextualize.- Returns:
- contextualized proxy instance that wraps execution of the
supply
method with context. - Throws:
IllegalArgumentException
- if an already-contextualizedSupplier
is supplied to this method.
-
withContextCapture
Returns a new
CompletableFuture
that is completed by the completion of the specified stage.The new completable future is backed by a ThreadContext rather than a ManagedExecutor. Therefore, the new stage and all dependent stages created from it, and so forth, have no default asynchronous execution facility and must raise
UnsupportedOperationException
for all*Async
methods 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
ManagedExecutor
class, 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
CompletionStage
that is completed by the completion of the specified stage.The new completion stage is backed by a ThreadContext rather than a ManagedExecutor. Therefore, the new stage and all dependent stages created from it, and so forth, have no default asynchronous execution facility and must raise
UnsupportedOperationException
for all*Async
methods 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
ManagedExecutor
class, 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.
-