-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue #103 propagation of third-party context types
Signed-off-by: Nathan Rauh <nathan.rauh@us.ibm.com>
- Loading branch information
Showing
9 changed files
with
770 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
api/src/main/java/jakarta/enterprise/concurrent/spi/ThreadContextProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/* | ||
* Copyright (c) 2021 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0, which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the | ||
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | ||
* version 2 with the GNU Classpath Exception, which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*/ | ||
package jakarta.enterprise.concurrent.spi; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
/** | ||
* Third party providers of thread context implement this interface to | ||
* participate in thread context capture and propagation. | ||
* <p> | ||
* Application code must never access the classes within this {@code spi} | ||
* package. Instead, application code uses the various interfaces that are defined | ||
* by the Jakarta Concurrency specification, such as | ||
* {@link jakarta.enterprise.concurrent.ManagedExecutorService ManagedExecutorService} | ||
* and {@link jakarta.enterprise.concurrent.ContextService ContextService}. | ||
* <p> | ||
* The {@code ThreadContextProvider} implementation and related classes are | ||
* packaged within the third party provider's JAR file. The implementation is made | ||
* discoverable via the {@link java.util.ServiceLoader ServiceLoader} mechanism. The JAR file | ||
* that packages it must include a file with the following name and location, | ||
* <p> | ||
* {@code META-INF/services/jakarta.enterprise.concurrent.spi.ThreadContextProvider} | ||
* <p> | ||
* The content of the aforementioned file must be one or more lines, each specifying | ||
* the fully qualified name of a {@code ThreadContextProvider} implementation | ||
* that is provided within the JAR file. | ||
* <p> | ||
* {@code ThreadContextProvider} implementations can return a | ||
* {@link ThreadContextSnapshot} that is also {@link java.io.Serializable Serializable} | ||
* from the {@link #currentContext} and {@link #clearedContext} methods | ||
* to allow for {@code Serializable} contextual proxies. | ||
* <p> | ||
* The Jakarta EE Product Provider must use the | ||
* {@code ServiceLoader} to identify all available implementations of | ||
* {@code ThreadContextProvider} that can participate in thread context capture | ||
* and propagation and must invoke them either to capture current thread context or establish | ||
* default thread context per the configuration of the | ||
* {@link jakarta.enterprise.concurrent.ContextServiceDefinition ContextServiceDefinition}, | ||
* or vendor-specific configuration, and execution properties such as | ||
* {@link jakarta.enterprise.concurrent.ManagedTask#TRANSACTION ManagedTask.TRANSACTION} | ||
* that override context propagation configuration. | ||
* | ||
* @since 3.0 | ||
*/ | ||
// TODO Should we include the second-to-last paragraph above allowing for captured context | ||
// to be serialized across JVMs? This might be useful for persistent timers/batch, but it is | ||
// also a lot of extra complexity that would be simpler to leave out. | ||
public interface ThreadContextProvider { | ||
/** | ||
* Captures from the current thread a snapshot of the provided thread context type. | ||
* | ||
* @param props execution properties, which are optionally provided | ||
* by some types of tasks and contextual proxies. | ||
* Thread context providers that do not supply or use execution properties | ||
* can ignore this parameter. | ||
* @return immutable snapshot of the provided type of context, captured from the | ||
* current thread. | ||
*/ | ||
public ThreadContextSnapshot currentContext(Map<String, String> props); | ||
|
||
/** | ||
* Returns empty/cleared context of the provided type. This context is not | ||
* captured from the current thread, but instead represents the behavior that you | ||
* get for this context type when no particular context has been applied to the | ||
* thread. | ||
* <p> | ||
* This is used in cases where the provided type of thread context should not be | ||
* propagated from the requesting thread or inherited from the thread of execution, | ||
* in which case it is necessary to establish an empty/cleared context in its place, | ||
* so that an action does not unintentionally inherit context of the thread that | ||
* happens to run it. | ||
* <p> | ||
* For example, a security context provider's empty/cleared context ensures there | ||
* is no authenticated user on the thread. A transaction context provider's | ||
* empty/cleared context ensures that any active transaction is suspended. | ||
* And so forth. | ||
* | ||
* @param props execution properties, which are optionally provided | ||
* by some types of tasks and contextual proxies. | ||
* Thread context providers that do not supply or use execution properties | ||
* can ignore this parameter. | ||
* @return immutable empty/default context of the provided type. | ||
*/ | ||
public ThreadContextSnapshot clearedContext(Map<String, String> props); | ||
|
||
// Similar to previous TODO comment, consider if we really want to support | ||
// serializable contextual proxies for third-party context types. | ||
/** | ||
* Deserializes a previously serialized {@link ThreadContextSnapshot}. | ||
* | ||
* @param bytes a {@code ThreadContextSnapshot} from this provider | ||
* that was serialized to an array of bytes by an | ||
* {@link java.io.ObjectOutputStream ObjectOutputStream}. | ||
* @return immutable snapshot of the provided type of context, deserialized | ||
* from the byte array. | ||
* @throws ClassNotFoundException if an error occurs during deserialization. | ||
* @throws IOException if an error occurs during deserialization. | ||
*/ | ||
public ThreadContextSnapshot deserialize(byte[] bytes) throws ClassNotFoundException, IOException; | ||
|
||
/** | ||
* Returns a human readable identifier for the type of thread context that is | ||
* captured by this {@code ThreadContextProvider} implementation. | ||
* <p> | ||
* To ensure portability of applications, this is typically be a keyword that | ||
* is defined by the same specification that defines the thread context type. | ||
* <p> | ||
* {@link jakarta.enterprise.concurrent.ContextServiceDefinition ContextServiceDefinition} | ||
* defines identifiers for built-in thread context types, including | ||
* {@link jakarta.enterprise.concurrent.ContextServiceDefinition#APPLICATION Application}, | ||
* {@link jakarta.enterprise.concurrent.ContextServiceDefinition#SECURITY Security}, and | ||
* {@link jakarta.enterprise.concurrent.ContextServiceDefinition#TRANSACTION Transaction}, | ||
* as well as the | ||
* {@link jakarta.enterprise.concurrent.ContextServiceDefinition#ALL_REMAINING Remaining} | ||
* identifer which covers all remaining context. | ||
* These identifiers must not be returned from this method. | ||
* <p> | ||
* Applications use a combination of built-in identifiers and those that are | ||
* defined by other specifications and third-party context | ||
* types when configuring a {@code ContextServiceDefinition} | ||
* to capture and propagate only specific types of thread context. | ||
* <p> | ||
* For example: | ||
* <pre> | ||
* {@code @ManagedExecutorDefinition(} | ||
* name = "java:module/concurrent/MyCustomContextExecutor", | ||
* maxAsync = 3, | ||
* context = {@code @ContextServiceDefinition(} | ||
* name = "java:module/concurrent/MyCustomContext", | ||
* propagated = MyCustomContextProvider.CONTEXT_NAME, | ||
* cleared = { ContextServiceDefinition.SECURITY, ContextServiceDefinition.TRANSACTION }, | ||
* unchanged = ContextServiceDefinition.ALL_REMAINING)) | ||
* </pre> | ||
* <p> | ||
* It is an error for multiple thread context providers of an identical type to be | ||
* simultaneously available. | ||
* | ||
* @return identifier for the provided type of thread context. | ||
*/ | ||
public String getThreadContextType(); | ||
} |
66 changes: 66 additions & 0 deletions
66
api/src/main/java/jakarta/enterprise/concurrent/spi/ThreadContextRestorer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) 2021 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0, which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the | ||
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | ||
* version 2 with the GNU Classpath Exception, which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*/ | ||
package jakarta.enterprise.concurrent.spi; | ||
|
||
/** | ||
* Restores the prior context on a thread after a contextual task or action completes. | ||
*/ | ||
@FunctionalInterface | ||
public interface ThreadContextRestorer { | ||
/** | ||
* Invoked by the Jakarta EE Product Provider to remove the thread context that | ||
* the {@link ThreadContextSnapshot} began on this thread and restore the previous | ||
* context that was on the thread prior to that point. The Jakarta EE Product Provider | ||
* must invoke the {@link #endContext endContext} method exactly | ||
* once for each {@code ThreadContextRestorer} instance that it obtains | ||
* and on the same thread from which the Jakarta EE Product Provider obtained it | ||
* by invoking {@link ThreadContextSnapshot#begin ThreadContextSnapshot.begin}. | ||
* <p> | ||
* Typically, patterns such as the following will be observed: | ||
* <pre> | ||
* restorerA1 = contextA_snapshot1.begin(); | ||
* restorerB1 = contextB_snapshot1.begin(); | ||
* restorerC1 = contextC_snapshot1.begin(); | ||
* ... | ||
* restorerC1.endContext(); | ||
* restorerB1.endContext(); | ||
* restorerA1.endContext(); | ||
* </pre> | ||
* However, more advanced sequences such as the following are also valid: | ||
* <pre> | ||
* restorerA1 = contextA_snapshot1.begin(); | ||
* restorerB1 = contextB_snapshot1.begin(); | ||
* ... | ||
* restorerC1 = contextC_snapshot1.begin(); | ||
* ... | ||
* restorerC1.endContext(); | ||
* ... | ||
* restorerB2 = contextB_snapshot2.begin(); | ||
* restorerC2 = contextC_snapshot2.begin(); | ||
* ... | ||
* restorerC2.endContext(); | ||
* restorerB2.endContext(); | ||
* ... | ||
* restorerB1.endContext(); | ||
* restorerA1.endContext(); | ||
* </pre> | ||
* | ||
* @throws IllegalStateException if invoked more than once on the same instance. | ||
* | ||
* @since 3.0 | ||
*/ | ||
public void endContext() throws IllegalStateException; | ||
} |
54 changes: 54 additions & 0 deletions
54
api/src/main/java/jakarta/enterprise/concurrent/spi/ThreadContextSnapshot.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2021 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0, which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the | ||
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | ||
* version 2 with the GNU Classpath Exception, which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*/ | ||
package jakarta.enterprise.concurrent.spi; | ||
|
||
/** | ||
* An immutable snapshot of a particular type of thread context. | ||
* <p> | ||
* The captured context represented by this snapshot can be applied to | ||
* any number of threads, including concurrently. | ||
* <p> | ||
* Any state that is associated with context applied to a thread should | ||
* be kept, not within the snapshot, but within the distinct | ||
* {@link ThreadContextRestorer} instance that this | ||
* {@code ThreadContextSnapshot} creates each time it is applied | ||
* to a thread. | ||
* | ||
* @since 3.0 | ||
*/ | ||
@FunctionalInterface | ||
public interface ThreadContextSnapshot { | ||
/** | ||
* Applies the captured thread context snapshot to the current thread and | ||
* returns a distinct {@link ThreadContextRestorer} instance. The | ||
* {@code ThreadContextRestorer} instance tracks the context's life cycle, | ||
* including any state that is associated with it or that is necessary for | ||
* restoring the previous context. | ||
* <p> | ||
* For each invocation of this method, the Jakarta EE Product Provider | ||
* must invoke the corresponding | ||
* {@link ThreadContextRestorer#endContext endContext} | ||
* method exactly once, such that the previous context is restored | ||
* on the thread. If the Jakarta EE Product Provider sequentially begins | ||
* multiple {@code ThreadContextRestorer} instances on a thread, | ||
* it must invoke the corresponding {@code endContext} methods in reverse | ||
* order. | ||
* | ||
* @return restorer instance that reverts the state of this context type | ||
* on the thread to what it was prior to applying this snapshot. | ||
*/ | ||
public ThreadContextRestorer begin(); | ||
} |
20 changes: 20 additions & 0 deletions
20
api/src/main/java/jakarta/enterprise/concurrent/spi/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright (c) 2021 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0, which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the | ||
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | ||
* version 2 with the GNU Classpath Exception, which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*/ | ||
|
||
/** | ||
* Interfaces for third-party providers of thread context to implement. | ||
*/ | ||
package jakarta.enterprise.concurrent.spi; |
Oops, something went wrong.