Extended Sessions for Isolated (Orchestrations)#3154
Merged
sophiatev merged 79 commits intoSep 18, 2025
Conversation
Merge dev into main, in preparation of archiving of `dev`
…none was attached to the orchestrator request
This was referenced Jul 14, 2025
sophiatev
marked this pull request as ready for review
July 14, 2025 21:36
andystaples
reviewed
Aug 1, 2025
andystaples
reviewed
Aug 1, 2025
|
|
||
| if (response.RequiresHistory) | ||
| { | ||
| throw new SessionAbortedException("The worker has since ended the extended session and needs an orchestration history to execute the orchestration request."); |
Contributor
There was a problem hiding this comment.
Some questions about this SessionAbortedException -
- Is
SessionAbortedExceptionretried indefinitely by Core or is there a limit? - Is it possible that the retry in Core happens so fast that the cache still hasn't been evicted from WebJobs, meaning that the exception will be thrown multiple times for the same task?
- Have we observed this exception being thrown and retried in practice?
- Any other gotchas we should document?
Contributor
Author
There was a problem hiding this comment.
- Very good question, I'm not sure actually. We ultimately abandon the work item in DT.Core here but I'm not sure if there is any limit on how many times it will retry the item.
- So this exception actually happens when the worker evicts the extended session earlier than the host does, so this is not a concern.
- Yes, everything looks good to me.
- Not that I can think of for now, but I think we should definitely test/discuss this more if we ultimately check this design into the main branch.
added 3 commits
August 1, 2025 14:48
…the cache with a more intelligent expiration scan frequency
bachuv
reviewed
Aug 1, 2025
| { | ||
| if (workerRequiresHistory) | ||
| { | ||
| throw new SessionAbortedException("The worker has since ended the extended session and needs an orchestration history to execute the orchestration request."); |
Contributor
There was a problem hiding this comment.
Can we add tests for extended sessions in the .NET Isolated testing framework? We could add a test for the use case when this exception gets thrown.
added 8 commits
August 1, 2025 16:54
sophiatev
force-pushed
the
stevosyan/extended-sessions-for-orchestrations-isolated
branch
from
September 11, 2025 19:03
dc06eff to
b3e9fff
Compare
cgillum
approved these changes
Sep 11, 2025
cgillum
approved these changes
Sep 15, 2025
cgillum
approved these changes
Sep 17, 2025
Member
There was a problem hiding this comment.
Were these protobuf changes already merged as part of a different PR?
Contributor
Author
There was a problem hiding this comment.
These are actually for a new feature I added to DTS, and they're showing up here just cause I pulled from the main protobuf branch (so sort of, yes)
nytian
approved these changes
Sep 18, 2025
sophiatev
deleted the
stevosyan/extended-sessions-for-orchestrations-isolated
branch
September 18, 2025 20:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR introduces enabling extended sessions for orchestrations in the .NET isolated framework. The way this is achieved is via an
IMemoryCachewhich maintains the extended sessions state in memory. The main changes in this PR are:FunctionsWorkerApplicationBuilderExtensions: Create this cache as a singleton upon worker startupFunctionsWorkerApplicationBuilderExtensions: Pass the cache to the dotnet SDK when executing the orchestration request.OutOfProcMiddlware: Extracts information about extended sessions passed in thedispatchContextfrom DT.Core to send to the worker. It also checks for the special edge case of a worker needing an orchestration history when none was attached to the request (OrchestratorResponse.requiresHistoryis true), and throws aSessionAbortedException, in which case DT.Core will end the session and retry the work item, this time indicating that a history should be attached with the request.RemoteOrchestratorConfigurationandRemoteOrchestratorContext: New fields added to pass additional information to the worker related to extended sessionsOrchestrationTriggerAttributeBindingProvider: Modified to only include past events in the orchestration request sent to the worker if the host indicates that this is necessary. (Past events are not included if this orchestration request is within an extended session, and not its first execution).DurableTaskOptions: Modified to not throw an exception in the case that extended sessions are enabled for .NET isolated (but an exception is still thrown for other OOProc languages).Other PRs:
Open questions
Is there a way to pass information from
DurableTaskOptionsto the worker upon startup? Specifically, theFunctionsWorkerApplicationBuilderExtensionsclass. Ideally, we would only make the cache for extended sessions if they are enabled (DurableTaskOptions.ExtendedSessionsEnabledis true), and set the cacheExpirationScanFrequencyto be some function of the user-specifiedDurableTaskOptions.ExtendedSessionIdleTimeoutInSeconds(maybe something along the lines ofExtendedSessionIdleTimeoutInSeconds/ 5).Design Callout
There are several avenues by which the worker can inform the host that it needs an orchestration history in the case that the worker has ended the extended session before the host. The worker will evict an extended session after the user-specified
extendedSessionIdleTimeoutInSecondsexpires. More specifically, what this means is that if the extended session is not accessed within that timeframe, the worker will evict it from the cache. In the meantime, it has to send the result of the orchestration work item back to the host, the host has to process this and commit it to storage, then wait for new orchestration messages, then send the worker the next work item once new messages arrive. From the host's perspective, theextendedSessionIdleTimeoutInSecondsapplies only to the amount of time we wait for new orchestration messages to arrive before ending the extended session. All that to say, there could perhaps be an appreciable number of situations where the worker ends the extended session before the host and will require a history.The current approach is perhaps the simplest - have the worker inform the host via the
requiresHistoryflag that it needs a history, in which case the host throws aSessionAbortedExceptionfromOutOfProcMiddleware. DT.Core already has all the logic to handle aSessionAbortedExceptionand retry the work item. The cons of this approach are that theSessionAbortedExceptionsurfaces to the logs and may alarm customers. There is also an added delay that comes from having DT.Core abort the orchestration work item entirely and try it again later in this approach. All that being said, perhaps the number of situations where this occurs could be reduced by just advising customers to up theirextendedSessionIdleTimeoutInSecondscount in the isolated model.An alternative is to have the worker call StreamInstanceHistory in the case that it has since ended the extended session and needs a history. This will not surface an exception to the customer, and will lead to less of a delay in processing the work item. But it could be much more complicated to implement as I am not sure how to get a client over to the
GrpcOrchestrationRunner. to accomplish this, and may require additional edge-case handling for all the network issues that could arise.Manual testing done thus far
SessionAbortedException. The work item will then be retried again.Performance testing
Two scenarios were run in in-process with extended sessions enabled/disabled, and in isolated with extended sessions enabled/disabled. Multiple trials were run, and the time it took to complete the orchestration was recorded as well as the number of times the history was loaded in each of these settings (with
extendedSessionIdleTimeoutInSecondsset to 30 seconds). The two scenarios tested wereSessionAbortedExceptionbeing thrown (so the worker ends the extended session before the host, and as expected, throws the exception which leads to a retry of the work item, this time with a history attached). In in-process, there was just one history load. Without ES, there were about 100 history loads in each.resolves #2905
Pull request checklist
pending_docs.mdrelease_notes.md/src/Worker.Extensions.DurableTask/AssemblyInfo.csdevandmainbranches and will not be merged into thev2.xbranch.