@@ -793,7 +793,8 @@ async Task<TaskOrchestrationWorkItem> LockNextTaskOrchestrationWorkItemAsync(boo
793793 TraceContext = currentRequestTraceContext ,
794794 } ;
795795
796- if ( ! this . IsExecutableInstance ( session . RuntimeState , orchestrationWorkItem . NewMessages , settings . AllowReplayingTerminalInstances , out string warningMessage ) )
796+ string warningMessage = await this . IsExecutableInstance ( session . RuntimeState , orchestrationWorkItem . NewMessages , settings . AllowReplayingTerminalInstances ) ;
797+ if ( ! string . IsNullOrEmpty ( warningMessage ) )
797798 {
798799 // If all messages belong to the same execution ID, then all of them need to be discarded.
799800 // However, it's also possible to have messages for *any* execution ID batched together with messages
@@ -1049,28 +1050,33 @@ internal static void TraceMessageReceived(AzureStorageOrchestrationServiceSettin
10491050 data . Episode . GetValueOrDefault ( - 1 ) ) ;
10501051 }
10511052
1052- bool IsExecutableInstance ( OrchestrationRuntimeState runtimeState , IList < TaskMessage > newMessages , bool allowReplayingTerminalInstances , out string message )
1053+ async Task < string > IsExecutableInstance ( OrchestrationRuntimeState runtimeState , IList < TaskMessage > newMessages , bool allowReplayingTerminalInstances )
10531054 {
10541055 if ( runtimeState . ExecutionStartedEvent == null && ! newMessages . Any ( msg => msg . Event is ExecutionStartedEvent ) )
10551056 {
10561057 var instanceId = newMessages [ 0 ] . OrchestrationInstance . InstanceId ;
10571058
10581059 if ( DurableTask . Core . Common . Entities . AutoStart ( instanceId , newMessages ) )
10591060 {
1060- message = null ;
1061- return true ;
1061+ return null ;
10621062 }
10631063 else
10641064 {
1065+ TaskMessage executionTerminatedEventMessage = newMessages . LastOrDefault ( msg => msg . Event is ExecutionTerminatedEvent ) ;
1066+ if ( executionTerminatedEventMessage is not null )
1067+ {
1068+ await this . trackingStore . UpdateStatusForTerminationAsync ( instanceId , ( ( ExecutionTerminatedEvent ) executionTerminatedEventMessage . Event ) . Input ) ;
1069+ return $ "Instance is { OrchestrationStatus . Terminated } ";
1070+ }
1071+
10651072 // A non-zero event count usually happens when an instance's history is overwritten by a
10661073 // new instance or by a ContinueAsNew. When history is overwritten by new instances, we
10671074 // overwrite the old history with new history (with a new execution ID), but this is done
10681075 // gradually as we build up the new history over time. If we haven't yet overwritten *all*
10691076 // the old history and we receive a message from the old instance (this happens frequently
10701077 // with canceled durable timer messages) we'll end up loading just the history that hasn't
10711078 // been fully overwritten. We know it's invalid because it's missing the ExecutionStartedEvent.
1072- message = runtimeState . Events . Count == 0 ? "No such instance" : "Invalid history (may have been overwritten by a newer instance)" ;
1073- return false ;
1079+ return runtimeState . Events . Count == 0 ? "No such instance" : "Invalid history (may have been overwritten by a newer instance)" ;
10741080 }
10751081 }
10761082
@@ -1080,12 +1086,10 @@ bool IsExecutableInstance(OrchestrationRuntimeState runtimeState, IList<TaskMess
10801086 runtimeState . OrchestrationStatus != OrchestrationStatus . Pending &&
10811087 runtimeState . OrchestrationStatus != OrchestrationStatus . Suspended )
10821088 {
1083- message = $ "Instance is { runtimeState . OrchestrationStatus } ";
1084- return false ;
1089+ return $ "Instance is { runtimeState . OrchestrationStatus } ";
10851090 }
10861091
1087- message = null ;
1088- return true ;
1092+ return null ;
10891093 }
10901094
10911095 async Task AbandonAndReleaseSessionAsync ( OrchestrationSession session )
@@ -1909,15 +1913,15 @@ public async Task<IList<OrchestrationState>> GetOrchestrationStateAsync(string i
19091913 /// </summary>
19101914 /// <param name="instanceId">Instance ID of the orchestration to terminate.</param>
19111915 /// <param name="reason">The user-friendly reason for terminating.</param>
1912- public Task ForceTerminateTaskOrchestrationAsync ( string instanceId , string reason )
1916+ public async Task ForceTerminateTaskOrchestrationAsync ( string instanceId , string reason )
19131917 {
19141918 var taskMessage = new TaskMessage
19151919 {
19161920 OrchestrationInstance = new OrchestrationInstance { InstanceId = instanceId } ,
19171921 Event = new ExecutionTerminatedEvent ( - 1 , reason )
19181922 } ;
19191923
1920- return SendTaskOrchestrationMessageAsync ( taskMessage ) ;
1924+ await SendTaskOrchestrationMessageAsync ( taskMessage ) ;
19211925 }
19221926
19231927 /// <summary>
0 commit comments