Interface PropagatedContext


public interface PropagatedContext
A mechanism for propagating state across threads that's easier to use and safer than ThreadLocal.

A propagated context is an immutable list of objects. Adding or deleting elements from a context creates a new context that must then be explicitly brought into scope by propagating it.

If an element wraps an existing thread local variable then it can implement ThreadPropagatedContextElement to take part in the enter-exit process.

In standard usage you would call getOrEmpty(), then plus(PropagatedContextElement) to add some data, then propagate(Supplier) to execute a lambda with the context in scope.

Since:
4.0.0
Author:
Denis Stepanov
  • Method Details

    • empty

      Returns an empty context.
      Returns:
      the empty context
    • getOrEmpty

      @NonNull static @NonNull PropagatedContext getOrEmpty()
      Returns the current context or an empty one.
      Returns:
      the current context or an empty one
    • get

      Returns the current context or throws an exception otherwise.
      Returns:
      the current context
    • find

      Returns an optional context.
      Returns:
      the current optional context
    • wrapCurrent

      @NonNull static @NonNull Runnable wrapCurrent(@NonNull @NonNull Runnable runnable)
      Captures the current context and returns a new Runnable that, when executed, will run the given runnable with the captured context in scope. If no context is in scope then the given callable is returned as-is.
      Parameters:
      runnable - The runnable
      Returns:
      new runnable or existing if the context is missing
    • wrapCurrent

      @NonNull static <V> @NonNull Callable<V> wrapCurrent(@NonNull @NonNull Callable<V> callable)
      Captures the current context and returns a new Callable that, when executed, will run the given callable with the captured context in scope. If no context is in scope then the given callable is returned as-is.
      Type Parameters:
      V - The callable type
      Parameters:
      callable - The callable
      Returns:
      new callable or existing if the context is missing
    • wrapCurrent

      @NonNull static <V> @NonNull Supplier<V> wrapCurrent(@NonNull @NonNull Supplier<V> supplier)
      Captures the current context and returns a new Supplier that, when executed, will run the given supplier with the captured context in scope. If no context is in scope then the given callable is returned as-is.
      Type Parameters:
      V - The supplier type
      Parameters:
      supplier - The supplier
      Returns:
      new supplier or existing if the context is missing
    • exists

      static boolean exists()
      Check if there is a context in scope.
      Returns:
      true if a context has been propagated.
    • plus

      Returns a new context extended with the given element. This doesn't add anything to the existing in-scope context (if any), so you will need to propagate it yourself. You can add multiple elements of the same type.
      Parameters:
      element - the element to be added
      Returns:
      the new context
    • minus

      Returns a new context without the provided element. This doesn't remove anything from the existing in-scope context (if any), so you will need to propagate it yourself. Elements are compared using Object.equals(Object).
      Parameters:
      element - The context element to be removed
      Returns:
      the new context
    • replace

      Creates a new context with the given element replaced. This doesn't change anything in the existing in-scope context (if any), so you will need to propagate it yourself. Elements are compared using Object.equals(Object).
      Parameters:
      oldElement - the element to be replaced
      newElement - the element that will replace it
      Returns:
      the new context
    • find

      <T extends PropagatedContextElement> Optional<T> find(@NonNull @NonNull Class<T> elementType)
      Finds the first element of the given type, if any exist.
      Type Parameters:
      T - The element's type
      Parameters:
      elementType - The element type
      Returns:
      element if found
    • findAll

      <T extends PropagatedContextElement> Stream<T> findAll(@NonNull @NonNull Class<T> elementType)
      Find all elements of the given type. The first element in the stream will be the last element added.
      Type Parameters:
      T - The element's type
      Parameters:
      elementType - The element type
      Returns:
      stream of elements of type
    • get

      <T extends PropagatedContextElement> T get(@NonNull @NonNull Class<T> elementType)
      Gets the first element of the given type.
      Type Parameters:
      T - The element's type
      Parameters:
      elementType - The element type
      Returns:
      an element
      Throws:
      NoSuchElementException - if no elements of that type are in the context.
    • getAllElements

      List<PropagatedContextElement> getAllElements()
      Gets all elements.
      Returns:
      all elements.
    • propagate

      Brings this context into scope, temporarily replacing the previous context (if any). The returned object must be closed to undo the propagation.
      Returns:
      auto-closeable block to be used in try-resource block.
    • wrap

      Returns a new runnable that runs the given runnable with this context in scope.
      Parameters:
      runnable - The runnable that will execute with this context in scope.
      Returns:
      new runnable
    • wrap

      @NonNull default <V> @NonNull Callable<V> wrap(@NonNull @NonNull Callable<V> callable)
      Returns a new callable that runs the given callable with this context in scope.
      Type Parameters:
      V - The callable return type
      Parameters:
      callable - The callable
      Returns:
      new callable
    • wrap

      @NonNull default <V> @NonNull Supplier<V> wrap(@NonNull @NonNull Supplier<V> supplier)
      Returns a new supplier that runs the given supplier with this context in scope.
      Type Parameters:
      V - The supplier return type
      Parameters:
      supplier - The supplier
      Returns:
      new supplier
    • propagate

      @NonNull default <V> V propagate(@NonNull @NonNull Supplier<V> supplier)
      Executes the given supplier with this context in scope, restoring the previous context when execution completes.
      Type Parameters:
      V - The supplier return type
      Parameters:
      supplier - The supplier
      Returns:
      the result of calling Supplier.get().