@@ -140,43 +140,50 @@ private async Task HandleActivationAsync(WorkflowActivation act)
140140 }
141141
142142 WorkflowActivationCompletion comp ;
143- DataConverter dataConverter = options . DataConverter ;
143+ DataConverter dataConverterNoContext = options . DataConverter ;
144+ DataConverter ? dataConverterWorkflowContext = null ;
144145 WorkflowCodecHelper . WorkflowCodecContext ? codecContext = null ;
145146
146147 // Catch any exception as a completion failure
147148 try
148149 {
149150 // Create data converter with context before doing any work
151+ string workflowId , workflowType ;
152+ IWorkflowCodecHelperInstance ? instanceForCodec ;
150153 if ( runningWorkflows . TryGetValue ( act . RunId , out var inst ) )
151154 {
152- codecContext = new (
153- Namespace : options . Namespace ,
154- WorkflowId : inst . Info . WorkflowId ,
155- WorkflowType : inst . Info . WorkflowType ,
156- TaskQueue : options . TaskQueue ,
157- Instance : inst ) ;
155+ workflowId = inst . Info . WorkflowId ;
156+ workflowType = inst . Info . WorkflowType ;
157+ instanceForCodec = inst ;
158158 }
159159 else if ( act . Jobs . Select ( j => j . InitializeWorkflow ) . FirstOrDefault ( s => s != null ) is { } initJob )
160160 {
161- codecContext = new (
162- Namespace : options . Namespace ,
163- WorkflowId : initJob . WorkflowId ,
164- WorkflowType : initJob . WorkflowType ,
165- TaskQueue : options . TaskQueue ,
166- Instance : null ) ;
161+ workflowId = initJob . WorkflowId ;
162+ workflowType = initJob . WorkflowType ;
163+ instanceForCodec = null ;
167164 }
168165 else
169166 {
170167 throw new InvalidOperationException ( "Missing workflow start (unexpectedly evicted?)" ) ;
171168 }
172- dataConverter = dataConverter . WithSerializationContext (
173- new ISerializationContext . Workflow (
174- Namespace : codecContext . Namespace , WorkflowId : codecContext . WorkflowId ) ) ;
175-
176- // Decode the activation if there is a codec
177- if ( dataConverter . PayloadCodec is { } decodeCodec )
169+ dataConverterWorkflowContext = dataConverterNoContext . WithSerializationContext (
170+ new ISerializationContext . Workflow ( options . Namespace , WorkflowId : workflowId ) ) ;
171+ // We'll only apply codec if one of the two converters has one
172+ if ( dataConverterNoContext . PayloadCodec != null ||
173+ dataConverterWorkflowContext . PayloadCodec != null )
178174 {
179- await WorkflowCodecHelper . DecodeAsync ( decodeCodec , codecContext , act ) . ConfigureAwait ( false ) ;
175+ codecContext = new (
176+ CodecNoContext : dataConverterNoContext . PayloadCodec ,
177+ CodecWorkflowContext : dataConverterWorkflowContext . PayloadCodec ,
178+ Namespace : options . Namespace ,
179+ WorkflowId : workflowId ,
180+ WorkflowType : workflowType ,
181+ TaskQueue : options . TaskQueue ,
182+ Instance : instanceForCodec ) ;
183+ }
184+ if ( codecContext != null )
185+ {
186+ await WorkflowCodecHelper . DecodeAsync ( codecContext , act ) . ConfigureAwait ( false ) ;
180187 }
181188
182189 // Log proto at trace level
@@ -191,8 +198,12 @@ private async Task HandleActivationAsync(WorkflowActivation act)
191198
192199 // If the workflow is not yet running, create it. We know that we will only get
193200 // one activation per workflow at a time, so GetOrAdd is safe for our use.
194- var workflow = runningWorkflows . GetOrAdd ( act . RunId , _ => CreateInstance ( act , dataConverter ) ) ;
195- codecContext = codecContext with { Instance = workflow } ;
201+ var workflow = runningWorkflows . GetOrAdd ( act . RunId , _ => CreateInstance (
202+ act , dataConverterNoContext , dataConverterWorkflowContext ) ) ;
203+ if ( codecContext != null )
204+ {
205+ codecContext = codecContext with { Instance = workflow } ;
206+ }
196207
197208 // Activate or timeout with deadlock timeout
198209 // TODO(cretz): Any reason for users to need to customize factory here?
@@ -230,9 +241,10 @@ private async Task HandleActivationAsync(WorkflowActivation act)
230241 comp = new ( ) { Failed = new ( ) } ;
231242 try
232243 {
233- // Failure converter needs to be in workflow context
234- comp . Failed . Failure_ = dataConverter . FailureConverter . ToFailure (
235- e , dataConverter . PayloadConverter ) ;
244+ // Failure converter needs to be in workflow context if available
245+ var dataConverterForFailure = dataConverterWorkflowContext ?? dataConverterNoContext ;
246+ comp . Failed . Failure_ = dataConverterForFailure . FailureConverter . ToFailure (
247+ e , dataConverterForFailure . PayloadConverter ) ;
236248 }
237249 catch ( Exception inner )
238250 {
@@ -244,12 +256,12 @@ private async Task HandleActivationAsync(WorkflowActivation act)
244256 // Always set the run ID of the completion
245257 comp . RunId = act . RunId ;
246258
247- // Encode the completion if there is a codec
248- if ( dataConverter . PayloadCodec is { } encodeCodec && codecContext is { } encodeContext )
259+ // Encode the completion if there is a codec context
260+ if ( codecContext != null )
249261 {
250262 try
251263 {
252- await WorkflowCodecHelper . EncodeAsync ( encodeCodec , encodeContext , comp ) . ConfigureAwait ( false ) ;
264+ await WorkflowCodecHelper . EncodeAsync ( codecContext , comp ) . ConfigureAwait ( false ) ;
253265 }
254266 catch ( Exception e )
255267 {
@@ -313,7 +325,10 @@ private async Task HandleCacheEvictionAsync(WorkflowActivation act, RemoveFromCa
313325 }
314326 }
315327
316- private IWorkflowInstance CreateInstance ( WorkflowActivation act , DataConverter dataConverter )
328+ private IWorkflowInstance CreateInstance (
329+ WorkflowActivation act ,
330+ DataConverter dataConverterNoContext ,
331+ DataConverter dataConverterWorkflowContext )
317332 {
318333 var init = act . Jobs . Select ( j => j . InitializeWorkflow ) . FirstOrDefault ( s => s != null ) ??
319334 throw new InvalidOperationException ( "Missing workflow start (unexpectedly evicted?)" ) ;
@@ -336,8 +351,10 @@ private IWorkflowInstance CreateInstance(WorkflowActivation act, DataConverter d
336351 InitialActivation : act ,
337352 Init : init ,
338353 Interceptors : options . Interceptors ,
339- PayloadConverter : dataConverter . PayloadConverter ,
340- FailureConverter : dataConverter . FailureConverter ,
354+ PayloadConverterNoContext : dataConverterNoContext . PayloadConverter ,
355+ PayloadConverterWorkflowContext : dataConverterWorkflowContext . PayloadConverter ,
356+ FailureConverterNoContext : dataConverterNoContext . FailureConverter ,
357+ FailureConverterWorkflowContext : dataConverterWorkflowContext . FailureConverter ,
341358 LoggerFactory : options . LoggerFactory ,
342359 DisableTracingEvents : options . DisableWorkflowTracingEventListener ,
343360 WorkflowStackTrace : options . WorkflowStackTrace ,
0 commit comments