Not able to update context passed via propagators

Hello,

I am using Custom Context Propagator to pass few parameters to all activities in a workflow.

public class RunContextPropagator implements ContextPropagator {

  @Override
  public String getName() {
    return this.getClass().getName();
  }

  @Override
  public Object getCurrentContext() {
    return RunContextManager.getContext();
  }

  @Override
  public void setCurrentContext(Object context) {
      RunHeaders headers = ((RunContext) context).getRunHeaders();
      RunContextManager.createContext(headers);
  }

  @Override
  public Map<String, Payload> serializeContext(Object context) {
    RunHeaders rawContext = ((RunContext) context).getRunHeaders();
    if (rawContext != null) {
      return Collections.singletonMap(RUN_CONTEXT,
          DataConverter.getDefaultInstance().toPayload(rawContext).get());
    } else {
      return Collections.emptyMap();
    }
  }

  @Override
  public Object deserializeContext(Map<String, Payload> context) {
    if (context.containsKey(RUN_CONTEXT)) {
      return DataConverter.getDefaultInstance()
          .fromPayload(context.get(RUN_CONTEXT), RunHeaders.class, RunHeaders.class);
    } else {
      return null;
    }
  }
}

As you can see, RunHeaders is the object that am planning to share with all the activities. It has three parameters, out of which 2 are set before the workflow starts.

RunContextManager.createContext(new RunHeaders(id, null, user.getUserId()));
WorkflowOptions options = WorkflowOptions.newBuilder()
          .setTaskQueue(RUN_QUEUE)
          .setContextPropagators(TemporalUtil.contextPropagators())
          .setWorkflowId(workflowId)
          .build();

      RunWorkflow workflow = workflowClient.newWorkflowStub(RunWorkflow.class, options);

      WorkflowExecution workflowExecution = WorkflowClient.start(workflow::run, scheduleId);

The other parameter actually has to be updated after completion of activity 1. But the update happens and its only visible in the scope of this activity class. Once the control comes back to workflow implementation class, only the first two values are present and this third value is again null.

@Slf4j
@Component
public class ActivityOneImpl implements ActivityOne {

  @Autowired
  WorkflowClient workflowClient;

  @Autowired
  RunService runService;

  @Override
  public void doRun(Long scheduleId) {
   ....
   String runId = runService.doOperation(scheduleId);
 
   RunContextManager.getContext().getRunHeaders().setRunId(runId);
  //This update in context is visible only until the scope of this class. Once the control comes back to workflow impl class, the updated value is again null and not getting reflected.
  }

Is it not possible to update context object in an activity and the same can’t be reflected to other subsequent activities?

I have also tried with MDC example that was mentioned in other posts. Even there, it’s the same behaviour. Anything updated as part of an activity is only visible within its scope. Once the control comes back to workflow or other activities, the same is not visible, only the ones that were maintained before the workflow started are visible through out the workflow run.

How can we update context propagated via ContextPropagators?

Context propagation works from outer-to-inner (see javadoc here).
So your context can propagate from your client to workflow, and workflow to activity, but propagating from inner-to-outer (for example activity to workflow) is not allowed (one reason is that it should not break workflow determinism).

Your workflow code can update the context with activity result for example, which then should be available in your next executed activity.

Thanks for your help Tihomir. It worked.