From 09ea5a6183c5ed8daf85bb8d1299e29e375d841f Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Fri, 11 Jul 2025 11:51:10 -0700 Subject: [PATCH 01/18] first commit --- .../TaskOrchestrationDispatcher.cs | 24 ++++++++++++++++--- .../TaskOrchestrationExecutor.cs | 5 +++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index 42564cddf..5c22fada1 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -224,6 +224,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) var isExtendedSession = false; + /* CorrelationTraceClient.Propagate( () => { @@ -233,6 +234,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) this.concurrentSessionLock.Release(); workItem.IsExtendedSession = isExtendedSession; }); + */ var processCount = 0; try @@ -242,6 +244,8 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) // If the provider provided work items, execute them. if (workItem.NewMessages?.Count > 0) { + // As long as we are in this execution loop, the extended session is maintained. + workItem.IsExtendedSession = true; bool isCompletedOrInterrupted = await this.OnProcessWorkItemAsync(workItem); if (isCompletedOrInterrupted) { @@ -252,7 +256,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) } // Fetches beyond the first require getting an extended session lock, used to prevent starvation. - if (processCount > 0 && !isExtendedSession) + if (processCount > 0) { isExtendedSession = this.concurrentSessionLock.Acquire(); if (!isExtendedSession) @@ -735,6 +739,8 @@ async Task ExecuteOrchestrationAsync(Orchestration dispatchContext.SetProperty(workItem); dispatchContext.SetProperty(GetOrchestrationExecutionContext(runtimeState)); dispatchContext.SetProperty(this.entityParameters); + dispatchContext.SetProperty("extendedSession", workItem.IsExtendedSession); + dispatchContext.SetProperty("includePastEvents", true); TaskOrchestrationExecutor? executor = null; @@ -786,12 +792,24 @@ async Task ResumeOrchestrationAsync(TaskOrchestrationWorkItem workItem) dispatchContext.SetProperty(cursor.TaskOrchestration); dispatchContext.SetProperty(cursor.RuntimeState); dispatchContext.SetProperty(workItem); + dispatchContext.SetProperty("extendedSession", true); + dispatchContext.SetProperty("includePastEvents", false); cursor.LatestDecisions = Enumerable.Empty(); await this.dispatchPipeline.RunAsync(dispatchContext, _ => { - OrchestratorExecutionResult result = cursor.OrchestrationExecutor.ExecuteNewEvents(); - dispatchContext.SetProperty(result); + // Check to see if the custom middleware intercepted and substituted the orchestration execution + // with its own execution behavior, providing us with the end results. If so, we can terminate + // the dispatch pipeline here. + // Need to make sure that this will be null for other OOProc scenarios (not isolated, like Java) + var resultFromMiddleware = dispatchContext.GetProperty(); + if (resultFromMiddleware != null) + { + return CompletedTask; + } + + OrchestratorExecutionResult resultFromOrchestrator = cursor.OrchestrationExecutor.ExecuteNewEvents(); + dispatchContext.SetProperty(resultFromOrchestrator); return CompletedTask; }); diff --git a/src/DurableTask.Core/TaskOrchestrationExecutor.cs b/src/DurableTask.Core/TaskOrchestrationExecutor.cs index c5e100a2f..e3dc6fc49 100644 --- a/src/DurableTask.Core/TaskOrchestrationExecutor.cs +++ b/src/DurableTask.Core/TaskOrchestrationExecutor.cs @@ -80,7 +80,10 @@ public TaskOrchestrationExecutor( { } - internal bool IsCompleted => this.result != null && (this.result.IsCompleted || this.result.IsFaulted); + /// + /// Whether or not the orchestration has completed. + /// + public bool IsCompleted => this.result != null && (this.result.IsCompleted || this.result.IsFaulted); /// /// Executes an orchestration from the beginning. From 276245c9a85778f209d385c1c35598f266344de1 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 14 Jul 2025 13:07:51 -0700 Subject: [PATCH 02/18] added some constants regarding extended sessions --- .../TaskOrchestrationDispatcher.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index 5c22fada1..26f0e230e 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -36,6 +36,17 @@ namespace DurableTask.Core /// public class TaskOrchestrationDispatcher { + /// + /// Whether or not the execution of the work item is within an extended session. + /// + public const string IsExtendedSession = "extendedSession"; + + /// + /// Whether or not to include past events in the orchestration history when executing the work item via middleware. + /// This assumes that the middleware is able to handle extended sessions and does not require history for replays. + /// + public const string IncludePastEvents = "includePastEvents"; + static readonly Task CompletedTask = Task.FromResult(0); readonly INameVersionObjectManager objectManager; @@ -739,8 +750,8 @@ async Task ExecuteOrchestrationAsync(Orchestration dispatchContext.SetProperty(workItem); dispatchContext.SetProperty(GetOrchestrationExecutionContext(runtimeState)); dispatchContext.SetProperty(this.entityParameters); - dispatchContext.SetProperty("extendedSession", workItem.IsExtendedSession); - dispatchContext.SetProperty("includePastEvents", true); + dispatchContext.SetProperty(IsExtendedSession, workItem.IsExtendedSession); + dispatchContext.SetProperty(IncludePastEvents, true); TaskOrchestrationExecutor? executor = null; @@ -792,8 +803,8 @@ async Task ResumeOrchestrationAsync(TaskOrchestrationWorkItem workItem) dispatchContext.SetProperty(cursor.TaskOrchestration); dispatchContext.SetProperty(cursor.RuntimeState); dispatchContext.SetProperty(workItem); - dispatchContext.SetProperty("extendedSession", true); - dispatchContext.SetProperty("includePastEvents", false); + dispatchContext.SetProperty(IsExtendedSession, true); + dispatchContext.SetProperty(IncludePastEvents, false); cursor.LatestDecisions = Enumerable.Empty(); await this.dispatchPipeline.RunAsync(dispatchContext, _ => From a8c878358542835ceb55435b138b00230953cfa4 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 14 Jul 2025 13:21:10 -0700 Subject: [PATCH 03/18] removed the chunk of code i commented out --- src/DurableTask.Core/TaskOrchestrationDispatcher.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index 26f0e230e..13d6345cd 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -234,19 +234,6 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) } var isExtendedSession = false; - - /* - CorrelationTraceClient.Propagate( - () => - { - // Check if it is extended session. - // TODO: Remove this code - it looks incorrect and dangerous - isExtendedSession = this.concurrentSessionLock.Acquire(); - this.concurrentSessionLock.Release(); - workItem.IsExtendedSession = isExtendedSession; - }); - */ - var processCount = 0; try { From 9d9c69fab04e7cbe0b3012e69f153706d213060f Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 14 Jul 2025 13:22:59 -0700 Subject: [PATCH 04/18] modified one comment slightly --- src/DurableTask.Core/TaskOrchestrationDispatcher.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index 13d6345cd..72dcfad64 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -799,7 +799,6 @@ await this.dispatchPipeline.RunAsync(dispatchContext, _ => // Check to see if the custom middleware intercepted and substituted the orchestration execution // with its own execution behavior, providing us with the end results. If so, we can terminate // the dispatch pipeline here. - // Need to make sure that this will be null for other OOProc scenarios (not isolated, like Java) var resultFromMiddleware = dispatchContext.GetProperty(); if (resultFromMiddleware != null) { From 4f0734f3f81b0441e6ae6d81db9bf09bb89a6cec Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Wed, 23 Jul 2025 11:42:54 -0700 Subject: [PATCH 05/18] slight variable name update as per PR comment --- src/DurableTask.Core/TaskOrchestrationDispatcher.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index 72dcfad64..ff163597a 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -233,7 +233,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) return; } - var isExtendedSession = false; + var concurrencyLockAcquired = false; var processCount = 0; try { @@ -254,10 +254,10 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) } // Fetches beyond the first require getting an extended session lock, used to prevent starvation. - if (processCount > 0) + if (processCount > 0 && !concurrencyLockAcquired) { - isExtendedSession = this.concurrentSessionLock.Acquire(); - if (!isExtendedSession) + concurrencyLockAcquired = this.concurrentSessionLock.Acquire(); + if (!concurrencyLockAcquired) { TraceHelper.Trace(TraceEventType.Verbose, "OnProcessWorkItemSession-MaxOperations", "Failed to acquire concurrent session lock."); break; @@ -284,7 +284,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) } finally { - if (isExtendedSession) + if (concurrencyLockAcquired) { TraceHelper.Trace( TraceEventType.Verbose, From b0de569dd80590149b373915eaeb41e7450bed92 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 4 Aug 2025 10:36:22 -0700 Subject: [PATCH 06/18] added private package names --- .../DurableTask.ApplicationInsights.csproj | 5 +++-- src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj | 5 +++-- src/DurableTask.Core/DurableTask.Core.csproj | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index f5e2f6ff2..4b6217a6c 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -12,9 +12,10 @@ 0 5 - 0 + 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) - $(VersionPrefix).0 + preview1 + $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) diff --git a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj index a3e4ee3c3..06468942c 100644 --- a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj +++ b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj @@ -22,8 +22,9 @@ 2 3 - 0 + 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) + preview1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) @@ -52,7 +53,7 @@ - + diff --git a/src/DurableTask.Core/DurableTask.Core.csproj b/src/DurableTask.Core/DurableTask.Core.csproj index 6668a8a95..eb0208a17 100644 --- a/src/DurableTask.Core/DurableTask.Core.csproj +++ b/src/DurableTask.Core/DurableTask.Core.csproj @@ -18,8 +18,9 @@ 3 3 - 0 + 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) + private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) From 78ea373445151c8c558aaa65b1719ffb1d4e1d12 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 4 Aug 2025 10:52:58 -0700 Subject: [PATCH 07/18] added a no warn to the application insights csproj to allow building the private packages --- .../DurableTask.ApplicationInsights.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index 4b6217a6c..6b9048549 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -5,7 +5,7 @@ netstandard2.0 Microsoft.Azure.DurableTask.ApplicationInsights - NU5125;NU5048;CS7035 + NU5125;NU5048;CS7035;NU5104 From 832abc81d4be4f59f04ef26ddc8e8c2df4a09bb1 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 4 Aug 2025 11:00:08 -0700 Subject: [PATCH 08/18] had the wrong suffix in two packages --- .../DurableTask.ApplicationInsights.csproj | 2 +- src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index 6b9048549..ab9635a53 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -14,7 +14,7 @@ 5 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) - preview1 + private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) diff --git a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj index 06468942c..62f5c6638 100644 --- a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj +++ b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj @@ -24,7 +24,7 @@ 3 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) - preview1 + private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) From 95df374d448fc8ba76f68b12279b2a2c5186389d Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 4 Aug 2025 11:05:05 -0700 Subject: [PATCH 09/18] updated the app insights csproj to build the preview package correctly --- .../DurableTask.ApplicationInsights.csproj | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index ab9635a53..3fb14d831 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -5,7 +5,7 @@ netstandard2.0 Microsoft.Azure.DurableTask.ApplicationInsights - NU5125;NU5048;CS7035;NU5104 + NU5125;NU5048;CS7035 @@ -20,10 +20,16 @@ $(VersionPrefix).$(FileVersionRevision) $(MajorVersion).$(MinorVersion).0.0 - - $(VersionPrefix) + + + $(VersionPrefix) + + + $(VersionPrefix)-$(VersionSuffix) + + From a2b1ac63feeff4517b9ad78cbc0987d720ac9719 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Mon, 4 Aug 2025 15:19:05 -0700 Subject: [PATCH 10/18] updating the preview package version --- .../DurableTask.ApplicationInsights.csproj | 2 +- src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj | 2 +- src/DurableTask.Core/DurableTask.Core.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index 3fb14d831..9536b9b81 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -14,7 +14,7 @@ 5 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private1 + private2 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) diff --git a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj index 62f5c6638..f51f207fc 100644 --- a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj +++ b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj @@ -24,7 +24,7 @@ 3 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private1 + private2 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) diff --git a/src/DurableTask.Core/DurableTask.Core.csproj b/src/DurableTask.Core/DurableTask.Core.csproj index eb0208a17..18e698870 100644 --- a/src/DurableTask.Core/DurableTask.Core.csproj +++ b/src/DurableTask.Core/DurableTask.Core.csproj @@ -20,7 +20,7 @@ 3 1 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private1 + private2 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) From 9ec72f4e050476b71f838d64b8bec4ee856c6895 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Fri, 8 Aug 2025 16:17:13 -0700 Subject: [PATCH 11/18] moving acquiring of the extended session lock before execution of the first work item to ensure that the worker does not store the extended session state unnecessarily in the isolated model --- .../TaskOrchestrationDispatcher.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index ff163597a..782a9c703 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -242,8 +242,10 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) // If the provider provided work items, execute them. if (workItem.NewMessages?.Count > 0) { - // As long as we are in this execution loop, the extended session is maintained. - workItem.IsExtendedSession = true; + concurrencyLockAcquired = this.concurrentSessionLock.Acquire(); + workItem.IsExtendedSession = concurrencyLockAcquired; + // Regardless of whether or not we acquired the concurrent session lock, we will make sure to execute this work item. + // If we failed to acquire it, we will end the extended session after this execution. bool isCompletedOrInterrupted = await this.OnProcessWorkItemAsync(workItem); if (isCompletedOrInterrupted) { @@ -253,15 +255,11 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) processCount++; } - // Fetches beyond the first require getting an extended session lock, used to prevent starvation. + // If we failed to acquire the concurrent session lock, we will end the extended session after the execution of the first work item if (processCount > 0 && !concurrencyLockAcquired) { - concurrencyLockAcquired = this.concurrentSessionLock.Acquire(); - if (!concurrencyLockAcquired) - { - TraceHelper.Trace(TraceEventType.Verbose, "OnProcessWorkItemSession-MaxOperations", "Failed to acquire concurrent session lock."); - break; - } + TraceHelper.Trace(TraceEventType.Verbose, "OnProcessWorkItemSession-MaxOperations", "Failed to acquire concurrent session lock."); + break; } TraceHelper.Trace(TraceEventType.Verbose, "OnProcessWorkItemSession-StartFetch", "Starting fetch of existing session."); From 1ac8877ab3b879ecc2f5be62d24645ecc661ac0c Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Fri, 8 Aug 2025 16:19:03 -0700 Subject: [PATCH 12/18] updating package numbers --- .../DurableTask.ApplicationInsights.csproj | 6 +++--- .../DurableTask.AzureStorage.csproj | 6 +++--- src/DurableTask.Core/DurableTask.Core.csproj | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index 9536b9b81..b72d89313 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -11,10 +11,10 @@ 0 - 5 - 1 + 6 + 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private2 + private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) diff --git a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj index f51f207fc..fbc5452ad 100644 --- a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj +++ b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj @@ -21,10 +21,10 @@ 2 - 3 - 1 + 5 + 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private2 + private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) diff --git a/src/DurableTask.Core/DurableTask.Core.csproj b/src/DurableTask.Core/DurableTask.Core.csproj index 18e698870..e2d8312f1 100644 --- a/src/DurableTask.Core/DurableTask.Core.csproj +++ b/src/DurableTask.Core/DurableTask.Core.csproj @@ -17,10 +17,10 @@ 3 - 3 - 1 + 5 + 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private2 + private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) From 3e626106130106e765f1f90e35c7dbc875b90eea Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Fri, 8 Aug 2025 17:01:25 -0700 Subject: [PATCH 13/18] fixing bug related to reacquiring the concurrent session lock unnecessarily --- src/DurableTask.Core/TaskOrchestrationDispatcher.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index 782a9c703..deafc533d 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -242,7 +242,11 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) // If the provider provided work items, execute them. if (workItem.NewMessages?.Count > 0) { - concurrencyLockAcquired = this.concurrentSessionLock.Acquire(); + // We only need to acquire the lock on the first execution within the extended session + if (!concurrencyLockAcquired) + { + concurrencyLockAcquired = this.concurrentSessionLock.Acquire(); + } workItem.IsExtendedSession = concurrencyLockAcquired; // Regardless of whether or not we acquired the concurrent session lock, we will make sure to execute this work item. // If we failed to acquire it, we will end the extended session after this execution. From 62da8362dc15cafd805c741da4d35d0f28e6b401 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Wed, 20 Aug 2025 17:53:22 -0700 Subject: [PATCH 14/18] pushing the etag bug fix here for now --- .../AzureStorageOrchestrationService.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs b/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs index 04a32e9fd..3bb239781 100644 --- a/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs +++ b/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs @@ -1215,12 +1215,18 @@ await this.CommitOutboundQueueMessages( this.orchestrationSessionManager.AddMessageToPendingOrchestration(session.ControlQueue, messages, session.TraceActivityId, CancellationToken.None); } } + // If the tracking store is of type InstanceStoreBackedTrackingStore, then it will throw a RequestFailedException catch (RequestFailedException rfe) when (rfe.Status == (int)HttpStatusCode.PreconditionFailed) { // Precondition failure is expected to be handled internally and logged as a warning. // The orchestration dispatcher will handle this exception by abandoning the work item throw new SessionAbortedException("Aborting execution due to failed precondition.", rfe); } + // If the tracking store is of type AzureStorageTrackingStore, then it will throw a DurableTaskStorageException which decorates the RequestFailedException + catch (DurableTaskStorageException dtse) when (dtse.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) + { + throw new SessionAbortedException("Aborting execution due to failed precondition.", dtse); + } catch (Exception e) { // TODO: https://github.com/Azure/azure-functions-durable-extension/issues/332 From e2561f63b4aa32abab99464a2b6269d0bba64cf1 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Wed, 20 Aug 2025 17:55:16 -0700 Subject: [PATCH 15/18] updating version number --- .../DurableTask.ApplicationInsights.csproj | 2 +- src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj | 2 +- src/DurableTask.Core/DurableTask.Core.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index b72d89313..e5b6ed25a 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -11,7 +11,7 @@ 0 - 6 + 7 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) private1 diff --git a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj index fbc5452ad..11f50b2fb 100644 --- a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj +++ b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj @@ -21,7 +21,7 @@ 2 - 5 + 6 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) private1 diff --git a/src/DurableTask.Core/DurableTask.Core.csproj b/src/DurableTask.Core/DurableTask.Core.csproj index e2d8312f1..25ad20d1c 100644 --- a/src/DurableTask.Core/DurableTask.Core.csproj +++ b/src/DurableTask.Core/DurableTask.Core.csproj @@ -17,7 +17,7 @@ 3 - 5 + 6 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) private1 From 098fb94891c3e9355d5f3cac96fa15f327d5fecb Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Thu, 11 Sep 2025 12:13:02 -0700 Subject: [PATCH 16/18] reverting csproj changes --- .../DurableTask.ApplicationInsights.csproj | 15 ++++----------- .../DurableTask.AzureStorage.csproj | 5 ++--- src/DurableTask.Core/DurableTask.Core.csproj | 3 +-- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj index e5b6ed25a..f5e2f6ff2 100644 --- a/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj +++ b/src/DurableTask.ApplicationInsights/DurableTask.ApplicationInsights.csproj @@ -11,25 +11,18 @@ 0 - 7 + 5 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private1 - $(VersionPrefix).0 + $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) $(MajorVersion).$(MinorVersion).0.0 + + $(VersionPrefix) - - - $(VersionPrefix) - - - $(VersionPrefix)-$(VersionSuffix) - - diff --git a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj index 11f50b2fb..1cfb9a2e9 100644 --- a/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj +++ b/src/DurableTask.AzureStorage/DurableTask.AzureStorage.csproj @@ -21,10 +21,9 @@ 2 - 6 + 4 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) @@ -53,7 +52,7 @@ - + diff --git a/src/DurableTask.Core/DurableTask.Core.csproj b/src/DurableTask.Core/DurableTask.Core.csproj index 25ad20d1c..6668a8a95 100644 --- a/src/DurableTask.Core/DurableTask.Core.csproj +++ b/src/DurableTask.Core/DurableTask.Core.csproj @@ -17,10 +17,9 @@ 3 - 6 + 3 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) - private1 $(VersionPrefix).0 $(VersionPrefix).$(FileVersionRevision) From 984850fb3bf38c5452749a946ac354097526c7f6 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Thu, 11 Sep 2025 12:14:02 -0700 Subject: [PATCH 17/18] reverting azure storage bug fix too --- .../AzureStorageOrchestrationService.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs b/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs index 3bb239781..04a32e9fd 100644 --- a/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs +++ b/src/DurableTask.AzureStorage/AzureStorageOrchestrationService.cs @@ -1215,18 +1215,12 @@ await this.CommitOutboundQueueMessages( this.orchestrationSessionManager.AddMessageToPendingOrchestration(session.ControlQueue, messages, session.TraceActivityId, CancellationToken.None); } } - // If the tracking store is of type InstanceStoreBackedTrackingStore, then it will throw a RequestFailedException catch (RequestFailedException rfe) when (rfe.Status == (int)HttpStatusCode.PreconditionFailed) { // Precondition failure is expected to be handled internally and logged as a warning. // The orchestration dispatcher will handle this exception by abandoning the work item throw new SessionAbortedException("Aborting execution due to failed precondition.", rfe); } - // If the tracking store is of type AzureStorageTrackingStore, then it will throw a DurableTaskStorageException which decorates the RequestFailedException - catch (DurableTaskStorageException dtse) when (dtse.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) - { - throw new SessionAbortedException("Aborting execution due to failed precondition.", dtse); - } catch (Exception e) { // TODO: https://github.com/Azure/azure-functions-durable-extension/issues/332 From 5075ebd5e125235e5093458e8d8747c994ce5ff1 Mon Sep 17 00:00:00 2001 From: Sophia Tevosyan Date: Thu, 11 Sep 2025 13:53:10 -0700 Subject: [PATCH 18/18] addressing PR feedback --- .../TaskOrchestrationDispatcher.cs | 17 ++--------------- src/DurableTask.Core/WorkItemMetadata.cs | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 src/DurableTask.Core/WorkItemMetadata.cs diff --git a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs index deafc533d..44adbbbd7 100644 --- a/src/DurableTask.Core/TaskOrchestrationDispatcher.cs +++ b/src/DurableTask.Core/TaskOrchestrationDispatcher.cs @@ -36,17 +36,6 @@ namespace DurableTask.Core /// public class TaskOrchestrationDispatcher { - /// - /// Whether or not the execution of the work item is within an extended session. - /// - public const string IsExtendedSession = "extendedSession"; - - /// - /// Whether or not to include past events in the orchestration history when executing the work item via middleware. - /// This assumes that the middleware is able to handle extended sessions and does not require history for replays. - /// - public const string IncludePastEvents = "includePastEvents"; - static readonly Task CompletedTask = Task.FromResult(0); readonly INameVersionObjectManager objectManager; @@ -739,8 +728,7 @@ async Task ExecuteOrchestrationAsync(Orchestration dispatchContext.SetProperty(workItem); dispatchContext.SetProperty(GetOrchestrationExecutionContext(runtimeState)); dispatchContext.SetProperty(this.entityParameters); - dispatchContext.SetProperty(IsExtendedSession, workItem.IsExtendedSession); - dispatchContext.SetProperty(IncludePastEvents, true); + dispatchContext.SetProperty(new WorkItemMetadata { IsExtendedSession = workItem.IsExtendedSession, IncludePastEvents = true }); TaskOrchestrationExecutor? executor = null; @@ -792,8 +780,7 @@ async Task ResumeOrchestrationAsync(TaskOrchestrationWorkItem workItem) dispatchContext.SetProperty(cursor.TaskOrchestration); dispatchContext.SetProperty(cursor.RuntimeState); dispatchContext.SetProperty(workItem); - dispatchContext.SetProperty(IsExtendedSession, true); - dispatchContext.SetProperty(IncludePastEvents, false); + dispatchContext.SetProperty(new WorkItemMetadata { IsExtendedSession = true, IncludePastEvents = false }); cursor.LatestDecisions = Enumerable.Empty(); await this.dispatchPipeline.RunAsync(dispatchContext, _ => diff --git a/src/DurableTask.Core/WorkItemMetadata.cs b/src/DurableTask.Core/WorkItemMetadata.cs new file mode 100644 index 000000000..ae3de4651 --- /dev/null +++ b/src/DurableTask.Core/WorkItemMetadata.cs @@ -0,0 +1,19 @@ +namespace DurableTask.Core +{ + /// + /// A class representing metadata information about a work item. + /// + public class WorkItemMetadata + { + /// + /// Gets or sets whether or not the execution of the work item is within an extended session. + /// + public bool IsExtendedSession { get; set; } + + /// + /// Gets or sets whether or not to include past events in the orchestration history when executing the work item via middleware. + /// This assumes that the middleware is able to handle extended sessions and does not require history for replays. + /// + public bool IncludePastEvents { get; set; } + } +}