@@ -108,6 +108,62 @@ static string GetActionsListForLogging(IReadOnlyList<P.OrchestratorAction> actio
108108 }
109109 }
110110
111+ static P . TaskFailureDetails ? EvaluateOrchestrationVersioning ( DurableTaskWorkerOptions . VersioningOptions ? versioning , string orchestrationVersion , out bool versionCheckFailed )
112+ {
113+ P . TaskFailureDetails ? failureDetails = null ;
114+ versionCheckFailed = false ;
115+ if ( versioning != null )
116+ {
117+ int versionComparison = TaskOrchestrationVersioningUtils . CompareVersions ( orchestrationVersion , versioning . Version ) ;
118+
119+ switch ( versioning . MatchStrategy )
120+ {
121+ case DurableTaskWorkerOptions . VersionMatchStrategy . None :
122+ // No versioning, breakout.
123+ break ;
124+ case DurableTaskWorkerOptions . VersionMatchStrategy . Strict :
125+ // Comparison of 0 indicates equality.
126+ if ( versionComparison != 0 )
127+ {
128+ failureDetails = new P . TaskFailureDetails
129+ {
130+ ErrorType = "VersionMismatch" ,
131+ ErrorMessage = $ "The orchestration version '{ orchestrationVersion } ' does not match the worker version '{ versioning . Version } '.",
132+ IsNonRetriable = true ,
133+ } ;
134+ }
135+
136+ break ;
137+ case DurableTaskWorkerOptions . VersionMatchStrategy . CurrentOrOlder :
138+ // Comparison > 0 indicates the orchestration version is greater than the worker version.
139+ if ( versionComparison > 0 )
140+ {
141+ failureDetails = new P . TaskFailureDetails
142+ {
143+ ErrorType = "VersionMismatch" ,
144+ ErrorMessage = $ "The orchestration version '{ orchestrationVersion } ' is greater than the worker version '{ versioning . Version } '.",
145+ IsNonRetriable = true ,
146+ } ;
147+ }
148+
149+ break ;
150+ default :
151+ // If there is a type of versioning we don't understand, it is better to treat it as a versioning failure.
152+ failureDetails = new P . TaskFailureDetails
153+ {
154+ ErrorType = "VersionError" ,
155+ ErrorMessage = $ "The version match strategy '{ orchestrationVersion } ' is unknown.",
156+ IsNonRetriable = true ,
157+ } ;
158+ break ;
159+ }
160+
161+ versionCheckFailed = failureDetails != null ;
162+ }
163+
164+ return failureDetails ;
165+ }
166+
111167 async ValueTask < OrchestrationRuntimeState > BuildRuntimeStateAsync (
112168 P . OrchestratorRequest orchestratorRequest ,
113169 ProtoUtils . EntityConversionState ? entityConversionState ,
@@ -308,56 +364,8 @@ async Task OnRunOrchestratorAsync(
308364 entityConversionState ,
309365 cancellationToken ) ;
310366
311-
312367 // If versioning has been explicitly set, we attempt to follow that pattern. If it is not set, we don't compare versions here.
313- if ( versioning != null )
314- {
315- int versionComparison = TaskOrchestrationVersioningUtils . CompareVersions ( runtimeState . Version , versioning . Version ) ;
316-
317- switch ( versioning . MatchStrategy )
318- {
319- case DurableTaskWorkerOptions . VersionMatchStrategy . None :
320- // No versioning, breakout.
321- break ;
322- case DurableTaskWorkerOptions . VersionMatchStrategy . Strict :
323- // Comparison of 0 indicates equality.
324- if ( versionComparison != 0 )
325- {
326- failureDetails = new P . TaskFailureDetails
327- {
328- ErrorType = "VersionMismatch" ,
329- ErrorMessage = $ "The orchestration version '{ runtimeState . Version } ' does not match the worker version '{ versioning . Version } '.",
330- IsNonRetriable = true ,
331- } ;
332- }
333-
334- break ;
335- case DurableTaskWorkerOptions . VersionMatchStrategy . CurrentOrOlder :
336- // Comparison > 0 indicates the orchestration version is greater than the worker version.
337- if ( versionComparison > 0 )
338- {
339- failureDetails = new P . TaskFailureDetails
340- {
341- ErrorType = "VersionMismatch" ,
342- ErrorMessage = $ "The orchestration version '{ runtimeState . Version } ' is greater than the worker version '{ versioning . Version } '.",
343- IsNonRetriable = true ,
344- } ;
345- }
346-
347- break ;
348- default :
349- // If there is a type of versioning we don't understand, it is better to treat it as a versioning failure.
350- failureDetails = new P . TaskFailureDetails
351- {
352- ErrorType = "VersionError" ,
353- ErrorMessage = $ "The version match strategy '{ versioning . MatchStrategy } ' is unknown.",
354- IsNonRetriable = true ,
355- } ;
356- break ;
357- }
358-
359- versionFailure = failureDetails != null ;
360- }
368+ failureDetails = EvaluateOrchestrationVersioning ( versioning , runtimeState . Version , out versionFailure ) ;
361369
362370 // Only continue with the work if the versioning check passed.
363371 if ( failureDetails == null )
@@ -421,6 +429,7 @@ async Task OnRunOrchestratorAsync(
421429 }
422430 else if ( versioning != null && failureDetails != null && versionFailure )
423431 {
432+ this . Logger . OrchestrationVersionFailure ( versioning . FailureStrategy . ToString ( ) , failureDetails . ErrorMessage ) ;
424433 if ( versioning . FailureStrategy == DurableTaskWorkerOptions . VersionFailureStrategy . Fail )
425434 {
426435 response = new P . OrchestratorResponse
@@ -442,6 +451,7 @@ async Task OnRunOrchestratorAsync(
442451 }
443452 else
444453 {
454+ this . Logger . AbandoningOrchestrationDueToVersioning ( request . InstanceId , completionToken ) ;
445455 await this . client . AbandonTaskOrchestratorWorkItemAsync (
446456 new P . AbandonOrchestrationTaskRequest
447457 {
0 commit comments