Add Serialization context for codecs and converters#2225
Add Serialization context for codecs and converters#2225yuandrew wants to merge 11 commits intotemporalio:masterfrom
Conversation
…Converter Introduces an opt-in mechanism that provides metadata (namespace, workflow ID, activity type, etc.) to converter implementations during serialization. This enables use cases like per-workflow encryption using workflow ID as associated data for a key. Adds WorkflowSerializationContext (for workflow-level payloads) and ActivitySerializationContext (for activity-level payloads), with opt-in interfaces for DataConverter, PayloadCodec, and FailureConverter. Context is provided at every serialization site: workflow execution, activity, local activity, child workflow, signal, query, update, continue-as-new, side effect, client operations, schedule client, and async activity completion. Matches the feature already implemented in Python, .NET, and Java SDKs. Closes temporalio#1352 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hOptions and RecordActivityHeartbeatByIDWithOptions, remove cmd.Or usage
| } | ||
|
|
||
| command := wc.commandsHelper.scheduleActivityTask(scheduleID, scheduleTaskAttr, startMetadata) | ||
| command := wc.commandsHelper.scheduleActivityTask(parameters.ScheduleID, scheduleTaskAttr, startMetadata) |
There was a problem hiding this comment.
This looks correct for the Go SDK itself, because workflowEnvironmentInterceptor.ExecuteActivity generates the ID. But this affects the bindings API, so binding callers now need to call env.GenerateSequence() and set ScheduleID. As is, I think this may be a breaking change for bindings callers (other SKDs built on top of the Go SDK).
There was a problem hiding this comment.
True, this will need to be called out in the PR description/release notes
There was a problem hiding this comment.
Ended up adding in backwards compatible checks that will GenerateSequence() in the same places we do today if bindings callers don't mirror this new behavior, so we should be good, no longer a breaking change
…, require callers to explicitly wrap context themselves. Use wfInfo.Namespace for signal external workflow, wrap context for testWorkflowEnvironmentImpl.executeWorkflow
|
|
||
| // CompleteActivityByIDWithOptions reports workflow activity completed with full context options. | ||
| func (wc *WorkflowClient) CompleteActivityByIDWithOptions(ctx context.Context, opts CompleteActivityByIDOptions) error { | ||
| if opts.ActivityID == "" || opts.WorkflowID == "" || opts.Namespace == "" { |
There was a problem hiding this comment.
Missing ensureInitialized call in new WithOptions methods
Medium Severity
CompleteActivityByIDWithOptions and CompleteActivityByActivityIDWithOptions are missing the wc.ensureInitialized(ctx) call that other WithOptions methods like CompleteActivityWithOptions (line 484), RecordActivityHeartbeatWithOptions (line 619), and RecordActivityHeartbeatByIDWithOptions (line 654) include. The original CompleteActivity delegates to CompleteActivityWithOptions which does call it, but CompleteActivityByID now delegates to CompleteActivityByIDWithOptions which doesn't, losing the initialization check that was previously handled by the shared code path.
Additional Locations (1)
| activityID = options.ActivityID | ||
| } else { | ||
| activityID = getStringID(scheduleID) | ||
| } |
There was a problem hiding this comment.
Sequence consumption order changes break workflow determinism
High Severity
GenerateSequence() for activity schedule IDs and child workflow IDs is now consumed in the interceptor layer before other operations, whereas previously it was consumed inside the environment's ExecuteActivity/ExecuteChildWorkflow. This changes the deterministic sequence ordering for replaying existing workflow histories. No SDK flag guards this behavioral change, so workflows recorded with the old code may fail non-determinism checks on replay with the new code.


A re-creation of #2149, as that did not properly capture the feature.
What was changed
Add SerializationContext — an opt-in mechanism that provides metadata (namespace, workflow ID, activity type,
etc.) to DataConverter, PayloadCodec, and FailureConverter implementations during serialization/deserialization.
New public API (converter package):
SerializationContextsealed interface with two implementations:WorkflowSerializationContext— for workflow-level payloads (workflow input/result, child workflow, signal,query, update, memo, continue-as-new)
ActivitySerializationContext— for activity-level payloads (activity input/result, heartbeat, failure details)DataConverterWithSerializationContext,PayloadCodecWithSerializationContext,FailureConverterWithSerializationContextWithDataConverterSerializationContext()/WithFailureConverterSerializationContext()helper functionsCodecDataConverter.WithSerializationContextauto-propagates context to both parent DC and codecsCompleteActivityWithOptions/CompleteActivityByIDWithOptions/CompleteActivityByActivityIDWithOptions/RecordActivityHeartbeatWithOptions/RecordActivityHeartbeatByIDWithOptions- New client functions that allow users to pass in proper activity metadata to pass into codecs. The existing methods don't have sufficient context information.Context is provided at every serialization site:
Why?
Enables use cases like per-workflow encryption (using workflow ID as associated data for a key), context-dependent
encoding, or audit logging — without requiring custom interceptors or thread-local hacks.
Matches the serialization context feature already implemented in Python, .NET, and Java.
Checklist
Closes Serialization context for codecs and converters #1352
How was this tested:
behavior
workflow, side effect, concurrent operations, signal external, query, update
QueryWorkflow, TerminateWorkflow
(side effect + activity + child workflow combined)
Any docs updates needed?
Note
Medium Risk
Touches core payload/failure serialization across workflows, activities, child workflows, and client APIs; incorrect context propagation could cause encode/decode mismatches or subtle behavior changes in custom codecs.
Overview
Adds an opt-in
converter.SerializationContextsystem (workflow- and activity-scoped) and wires it throughDataConverter,PayloadCodec, andFailureConvertervia newWithSerializationContextinterfaces and helper wrappers.Propagates these contexts throughout the SDK’s serialization sites (workflow/activity/local activity execution, child workflows, signals/queries/updates/continue-as-new, schedules, and client operations), including per-operation context-aware converters for decoding cancellations and failures.
Extends the public client API with
*WithOptionsvariants for async activity completion/heartbeats so callers can supply activity metadata for context-aware codecs, and adds extensive unit/integration coverage to validate context propagation and round-trip behavior.Written by Cursor Bugbot for commit 80d1311. This will update automatically on new commits. Configure here.