Skip to content

Latest commit

 

History

History
109 lines (92 loc) · 4.14 KB

File metadata and controls

109 lines (92 loc) · 4.14 KB

Builders for ManagedExecutor and ThreadContext

The MicroProfile Context Propagation spec defines a fluent builder API to programmatically obtain instances of ManagedExecutor and ThreadContext. Builder instances are obtained via static builder() methods on ManagedExecutor and ThreadContext.

Example ManagedExecutor Builder Usage

import java.util.concurrent.CompletionStage;
import java.util.concurrent.CompletableFuture;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.microprofile.context.ManagedExecutor;
import org.eclipse.microprofile.context.ThreadContext;

public class ExampleServlet extends HttpServlet {
    ManagedExecutor executor;

    public void init(ServletConfig config) {
        executor = ManagedExecutor.builder()
                                  .propagated(ThreadContext.APPLICATION)
                                  .cleared(ThreadContext.ALL_REMAINING)
                                  .maxAsync(5)
                                  .build();
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res) {
       completionStage = executor.runAsync(task1)
                             .thenRunAsync(task2)
                             ...
    }

    public void destroy() {
        executor.shutdown();
    }
}

Applications are encouraged to cache and reuse ManagedExecutor instances. It is the responsibility of the application to shut down ManagedExecutor instances that are no longer needed, so as to allow the container to efficiently free up resources.

Example ThreadContext Builder Usage

import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Supplier;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.microprofile.context.ThreadContext;

public class ExampleServlet extends HttpServlet {
    ThreadContext threadContext;

    public void init(ServletConfig config) {
        threadContext = ThreadContext.builder()
                            .propagated(ThreadContext.APPLICATION, ThreadContext.SECURITY)
                            .unchanged()
                            .cleared(ThreadContext.ALL_REMAINING)
                            .build();
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res) {
        Function<Long, Long> contextFn = threadContext.contextualFunction(x -> {
            ... operation that requires security & application context
            return result;
        });

        // By using java.util.concurrent.CompletableFuture.supplyAsync rather
        // than a managed executor, context propagation is unpredictable,
        // except for the contextFn action that we pre-contextualized using
        // ThreadContext above.
        stage = CompletableFuture.supplyAsync(supplier)
                                 .thenApplyAsync(function1)
                                 .thenApply(contextFn)
                                 ...
    }
}

Reuse of Builders

Instances of ManagedExecutor.Builder and ThreadContext.Builder retain their configuration after the build method is invoked and can be reused. Subsequent invocations of the build() method create new instances of ManagedExecutor and ThreadContext that operate independently of previously built instances.