Need to understand how Threads work with temporal

Hello ,
We have started working with Temporal with spring
our flow goes like this :
controller → service → temporal WorkflowImpl ->ActivityImpl → service

so if we set some value in ThreadLocal at controller layer , still we could get the same at ActivityImpl
how is it possible?
Could you please help us understanding how threads work ? whether at workflowImpl level new threads are created ? As while logging we could see that thread names are different at service layer and workflow layers.

One more question :
How can I invoke this workflow synchronously?

WorkflowStub stub = workflowClient.newUntypedWorkflowStub("createUser", options);
stub.start(user , null, null);

below code works as expected , but I need to invoke untyped workflow synchronously

 HelloWorldWorkflow workflow = client.newWorkflowStub(HelloWorldWorkflow.class, options);
        // Synchronously execute the Workflow and wait for the response.
        String greeting = workflow.getGreeting("World");
1 Like

Regarding workflowClient.newUntypedWorkflowStub
right after you start the workflow you can call
stub.getResult(...);
getResult will perform a long poll on the server waiting for the workflow completion event.

For the thread questions, within your workflow code you should use io.temporal.workflow.WorkflowLocal or io.temporal.workflow.WorkflowThreadLocal
Activities have to be thread safe as you are registering a single activity instance with the worker.

Thanks so much @tihomir
Is there doc I can refer to understand the threads mechanism better?
threads can become a major issue for us if we don’t have much clarity as we are using spring with temporal Java-sdk

Take a look at Workflows in Java | Temporal documentation
Definitely need a similar section for Activities and will work on it.
Let me know what you think is missing there or can be improved.

Such context propagation is possible through interceptors. See how opentracing support which is essentially context propagation is implemented. It is 100% interceptor based.

@maxim
Actually even without doing anything still we are getting the values at activityImpl from ThreadLocal, is it expected ?
As the threads are different . Please correct me if I am missing anything.

I doubt. The threads used by activities are owned by a separate thread pool.

Thanks @maxim ,
even we had this doubt too,

is there a way we can execute entire workflow in one thread ?
Or something which can fix the below issue ?

flow :

controller -> workflow[impl & activity]  -> service
<< controller calls workflow stubs>>
<<service bean is injected in workflow using dependency injection>> 

request 1 sets value xyz in ThreadLocal , at service we get xyz [ from inheritableThread values]
request 2 sets value abc in ThreadLocal BUT here at service we are still getting “xyz” and not “abc”

Does temporal provides any way that can fix our issue.
Considering we are extensively relying on the threadLocal values at service layer, it has become a blocker for us.

Does temporal provides any way that can fix our issue.

Yes, you have to use interceptors or ContextPropagator to pass your context between all the threads and the headers.

ok @maxim ,
how to get the values from context Propagator ?
is it based on implementation where if MDC is used , then MDC.get(“key”)
or
Temporal java-sdk exposes some mechanism/api to access it from workflow/activity classes?

You can implement a custom context propagator by implementing the ContextPropagator interface, see sample here: sdk-java/ContextPropagationTest.java at master · temporalio/sdk-java · GitHub
and also look at the tests there they help.

1 Like