Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Modifying Shared State in Workflow Code

Tip

Workflow code runs in a shared worker process -- modifying global variables, singletons, or shared maps creates race conditions and breaks determinism on replay.

A Temporal worker runs many workflow executions concurrently in the same process. When workflow code writes to a global variable, every concurrent execution races to read and write the same memory without synchronization. On replay, the global state is in a completely different condition than it was during the original execution, causing non-determinism errors.

modifying_shared_state_in_workflow_code/workflow.go

// BAD: shared mutable state
var processedCount int

func MyWorkflowV1(ctx workflow.Context) error {
	processedCount++ // Data race! Non-deterministic on replay!
	if processedCount > 100 {
		if err := workflow.ExecuteActivity(ctx, AlertActivity).Get(ctx, nil); err != nil {
			return err
		}
	}
	// ...
	return nil
}

modifying_shared_state_in_workflow_code/workflow.go

// GOOD: local state
func MyWorkflowV2(ctx workflow.Context) error {
	processedCount := 0 // Local to this workflow execution
	_ = processedCount
	// ...
	return nil
}

Keep all workflow state local to the workflow function. Use activities for anything that needs to interact with external or shared state (databases, caches, counters). Be cautious with injected dependencies -- a shared logger with mutable state or a shared cache can cause the same problems if the workflow modifies that shared object.