How to build a new workflow.Context

Hello, i’m stuck in the case same as the following example.

In my workflow, i start some normally go code(doSth1).
and then by some condition i want execute an activity in the code, but i lost the workflow.Context.

Should i build a new workflow.Context from context.context and how.

thanks

There are a couple of issues:

  1. You are calling doSth1 with a background context.
  2. In doSth1, the ctx type should be workflow.Context

See corrected code:

func YourWorkflow1(ctx workflow.Context) error {
  doSth1(ctx)
  return nil
}

func doSth1(ctx workflow.Context) error {
  ...
}

thanks your reply. but doSth1 also was invoked by other code executing not in temproal workflow. I cannot refactor it to workflow.Context.

but doSth1 also was invoked by other code executing not in temproal workflow

Ok, so looks like you are trying to reuse doSth1 and doSth2 for both Temporal and non-temporal code path branched off by env var?

What you could do is to bring activity execution inside the workflow, e.g.

func YourWorkflow1(ctx workflow.Context) error {
	ao := workflow.ActivityOptions{
		StartToCloseTimeout: 10 * time.Second,
	}
	ctx = workflow.WithActivityOptions(ctx, ao)
	err = workflow.ExecuteActivity(ctx, doSth1).Get(ctx, nil)
    ...
}

func doSth1(ctx context.Context) error {
    ...
}

thanks again.
Yes, I know that. In fact i want to know is it possible and reliable to convert context.Context to workflow.Context or build a new workflow.Context from some info.

No probs Rongtao.

Short answer is no, you cannot reliably convert context.Context to workflow.Context or build from scratch.

Longer answer:

Temporal designed it’s own workflow.Context interface and the underlying implementation in order to handle concurrency in workflow execution and history replay deterministically.

The reason is that in Go, select chooses channels randomly when multiple of them are available to proceed. This would make Workflow history reply non-deterministic. To overcome that, Temporal implemented it’s own channel, selector, and it’s strictly ordered signal processing.

In addition to that, Temporal relies heavily on workflow.Context to propagate other info related to the execution env: sdk-go/internal_workflow.go at f2e9c85c91563f3e6a96fad9beaefe637562b81f · temporalio/sdk-go · GitHub. I don’t think it’s practical to rebuild all of these and make use of the context reliability in your workflow execution.

Having said that, Activity does not have these determinism concerns and does rely on the vanilla context.Context hence my earlier suggestion.

@taonic Is it possible to append to a workflow.Context? I wanted to do it in the context of an interceptor.

What do you mean by append? workflow.Context supports workflow.WithValue.

Sorry, for some reason at first I didn’t see that With.Value

@maxim if you have time, can you take a look at Adding tags to temporal metrics I’m trying to figure out if this is the best way to do this.