Context Propagation

Context:

I have an application using Temporal and Spring Boot where i want to propagate the JWT of the user who started the workflow to activities, so that the token is propagated across API calls leaving my service. For that purpose I am using ContextPropagator from the Java SDK.

In my context propagtor, setCurrentContext uses SecurityContextHolder of Spring Security to store the token. SecurityContextHolder uses under the hood a ThreadLocal variable. getCurrentContext fetches the token from SecurityContextHolder and then clears the SecurityContext. I am clearing the SecurityContext since to my understanding, there is no guarantee that the thread currently being used to execute the workflow will continue the execution once an activity is called and done processing and might actually start executing a different workflow. So in order to avoid leaking the SecurityContext across workflows re-using the same thread, I am clearing the security context upon any call to Temporal, more specifically: upon calling getCurrentContext.

Problem: The context is not being propagated upon activity completion. Example:

class MyWorkflow implements IMyWorkflow {
    private FirstActivity firstActivity = Workflow.newActivityStub(FirstActivity.class);
    private SecondActivity secondActivity = Workflow.newActivityStub(SecondActivity.class);


    @Override
    void execute() {
        // SecurityContext exists here and is propagated correctly to FirstActivity
        firstActivity.doSomething();
        // SecurityContext is empty here
        secondActivity.doSomethingElse();
    }
}

Taking a closer look at the events in Temporal, I noticed that the headers of the ActivityTaskCompleted and the following WorkflowTaskScheduled are empty, and do not hold the same context that was set upon ActivityTaskScheduled.

Question: Is this behavior intended? How would the propagation work in case a different thread continued the workflow execution after an activity execution is completed? How can we guarantee that any static variable set during context propagation is correct if we cannot clear it upon propagating the context?

Question also posted here: Context propagation in Temporal - Stack Overflow

I would recommend not using ContextPropagator but implementing it using interceptors directly. See temporal-opentracing for inspiration.

Inside the workflow code don’t use ThreadLocal, use its workflow safe equivalent WorkflowThreadLocal instead.

1 Like