Skip to content

Extended session support - #309

Open
Usein Mambediiev (usemam) wants to merge 6 commits into
microsoft:mainfrom
usemam:fix-issue-56
Open

Extended session support#309
Usein Mambediiev (usemam) wants to merge 6 commits into
microsoft:mainfrom
usemam:fix-issue-56

Conversation

@usemam

Copy link
Copy Markdown
Contributor

Summary

Keep orchestration in memory until it's idle for a configured timeout.
When extended sessions enabled, check-pointing the orchestration instance does not reset Instances.LockedBy/LockExpiration values. A SqlOrchestrationSession instance is provided to the dispatcher, through which new messages for the orchestration instance are fetched.

Links

@usemam

Copy link
Copy Markdown
Contributor Author

Chris Gillum (@cgillum) sorry to bother - could you please provide your feedback? 🙏

@usemam

Copy link
Copy Markdown
Contributor Author

Chris Gillum (@cgillum) , apologies for pinging - could you please review this one? 🙏

@cgillum

Copy link
Copy Markdown
Member

Hey Usein Mambediiev (@usemam), sorry for missing your pings! Adding sophiatev to take a look at this PR as she has the most context on extended sessions these days.

@sophiatev

Copy link
Copy Markdown
Contributor

Hey Usein Mambediiev (@usemam) can you fix the merge conflicts, then I'll take a look :)

@usemam

Copy link
Copy Markdown
Contributor Author

sophiatev apologies about the delay. Conflicts are fixed now. Please take a look. Thank you!

@andystaples andystaples left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together. The overall approach—implementing Core's IOrchestrationSession, defaulting the feature off, and retaining the SQL instance lock across checkpoints—is the right model for this backend. I found the following blockers that need to be addressed before merge:

  1. The PR does not compile. SqlOrchestrationSession implements IOrchestrationSession but does not implement EndSessionAsync(). The current head fails with CS0535 for netstandard2.0, net8.0, and net10.0. A no-op implementation is appropriate if lock release remains in ReleaseTaskOrchestrationWorkItemAsync.

  2. Lease ownership is not generation-safe. Every session receives the process-wide lockedByValue, while checkpoint, fetch, renew, and release identify ownership using that reusable value. If a lease expires and the same process reacquires the instance, the old session can still checkpoint or clear the replacement session's lease. Also, the checkpoint guard checks LockedBy but not whether LockExpiration is still valid, and _RenewOrchestrationLocks has no owner guard. Please use a unique token per lock acquisition and validate that token plus an unexpired lease in checkpoint/fetch/renew/release; lock-loss should surface as SessionAbortedException.

  3. The retained EventPayloadMap collides across ContinueAsNew generations. Value-tracked payloads are keyed only by (EventType, TaskEventId) and inserted with Dictionary.Add. Activity and sub-orchestration IDs restart after ContinueAsNew, so scheduling ID 0 in a later generation can throw before checkpointing. Reset/replace mappings after a successful checkpoint or include execution identity in the key.

  4. _FetchOrchestrationMessages returns an undefined event order. It uses TOP (@BatchSize) without ORDER BY. Core only ensures that ExecutionStarted is first; it does not restore order among external events or task responses. Please add ORDER BY N.SequenceNumber ASC.

  5. All sessions share the service's stateful BackoffPollingHelper. The mutable interval, exponent, Random, and auto-reset event are shared with the main orchestration poller and every concurrent session. Session polling therefore changes global polling latency, and reset signals can wake an unrelated waiter. Each session should own an independent helper and reset it after finding work.

  6. Azure Functions timeout mapping is inconsistent with Azure Storage. SqlDurabilityOptions only assigns ExtendedSessionIdleTimeout when the common option is greater than zero. Explicit zero/negative values silently retain SQL's 30-second default, while Azure Storage clamps the same option to zero; this can also disagree with the isolated worker cache configuration. Please align the mapping (for example, clamp to zero) or reject invalid values consistently.

Please add repository-local coverage for:

  • the Core interface/build contract;
  • lease expiry followed by same-process reacquisition, proving stale checkpoint, renew, fetch, and release calls are rejected;
  • order-sensitive external events or responses across a session;
  • ContinueAsNew followed by activities and sub-orchestrations whose task IDs restart;
  • Azure Functions adapter mapping for default, custom, zero, and negative timeout values;
  • Durable Entity behavior in both queue modes, or explicitly prevent sessions from being attached to entity work items until supported;
  • graceful shutdown/drain and lock release.

The cross-repository package pins, extension bundle publication, public docs/tooling schemas, and rollout telemetry can be handled as maintainer-owned follow-ups rather than requirements for this contribution.

@andystaples

andystaples commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Hi Usein Mambediiev (@usemam) , thanks for your contribution. Independent of Sophia's review, I had an agent take a look and it produced the findings above. Please take a look and address where applicable, and thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants