Skip to content

Await export job deletion before returning success - #837

Merged
wangbill (YunchuWang) merged 2 commits into
mainfrom
yunchuwang-export-deletion-acknowledgement
Nov 5, 2026
Merged

wangbill (YunchuWang) merged 2 commits into
mainfrom
yunchuwang-export-deletion-acknowledgement

Conversation

@YunchuWang

Copy link
Copy Markdown
Member

Summary

What changed?

  • Retain the instance ID of the ExecuteExportJobOperationOrchestrator command that executes ExportJob.Delete, and await its completion with inputs/outputs and the caller's cancellation token before starting linked-orchestration cleanup.
  • Require OrchestrationRuntimeStatus.Completed; otherwise throw an InvalidOperationException containing the job ID and available failure message, using the existing client error logging/rethrow path.
  • Strengthen client tests for pending-command ordering, successful cleanup, unsuccessful/nonterminal results, command-wait RPC errors, cancellation, and graceful linked-orchestration NotFound handling.

Why is this change needed?

  • Scheduling an orchestration acknowledges submission, not completion of the entity operation. Previously, DeleteAsync could return successfully while the delete command was still pending and never observe its failure.
  • This follows the completion/status-check pattern already used by this client's CreateAsync and the scheduled-task client's DeleteAsync.

Issues / work items

  • Resolves: N/A; no existing issue tracks this correction.
  • Related Export History job #494 (original export-history implementation).

Project checklist

  • Release notes are not required for the next release
    • Otherwise: Notes added to release_notes.md
  • Backport is not required
    • Otherwise: Backport tracked by issue/PR #issue_or_pr
  • All required tests have been added/updated (unit tests, E2E tests)
  • Breaking change?
    • If yes:
      • Impact: N/A; no public API signatures, protocol, or serialization changes. Waiting for the delete acknowledgement and surfacing its failures are the intended correction.
      • Migration guidance: N/A.

AI-assisted code disclosure (required)

Was an AI tool used? (select one)

  • No
  • Yes, AI helped write parts of this PR (e.g., GitHub Copilot)
  • Yes, an AI agent generated most of this PR

If AI was used:

  • Tool(s): GitHub Copilot coding agent (GPT-6.1 Sol).
  • AI-assisted areas/files: src/ExportHistory/Client/DefaultExportHistoryJobClient.cs and test/ExportHistory.Tests/Client/DefaultExportHistoryJobClientTests.cs.
  • What you changed after AI output: The agent iterated the regression tests to compare normalized entity IDs, reviewed the final diff, and retained trailing newlines to avoid introducing StyleCop warnings. No separate human edits or sign-off are claimed.

AI verification (required if AI was used):

  • I understand the code and can explain it
  • I verified referenced APIs/types exist and are correct
  • I reviewed edge cases/failure paths (timeouts, retries, cancellation, exceptions)
  • I reviewed concurrency/async behavior
  • I checked for unintended breaking or behavior changes

The verification above was performed by the coding agent.


Testing

Automated tests

  • Result: Final focused tests and all-target package build passed. The strengthened deletion tests failed against the original production implementation before the fix, as expected.
  • dotnet restore .\test\ExportHistory.Tests\ExportHistory.Tests.csproj --configfile .\nuget.config --verbosity minimal — passed after the initial no-restore run found missing assets in the new worktree.
  • dotnet test .\test\ExportHistory.Tests\ExportHistory.Tests.csproj --no-restore --filter FullyQualifiedName~DefaultExportHistoryJobClientTests --verbosity minimal — original baseline: 13 passed; final implementation: 21 passed, 0 failed, 0 skipped.
  • dotnet test .\test\ExportHistory.Tests\ExportHistory.Tests.csproj --no-restore --filter 'FullyQualifiedName~DefaultExportHistoryJobClientTests&FullyQualifiedName~DeleteAsync' --verbosity minimal — expected pre-fix failure: all 10 strengthened deletion cases failed against unchanged production code. These cases are included in the final 21 passing tests above.
  • dotnet build .\src\ExportHistory\ExportHistory.csproj --configuration Release --no-restore --no-incremental --verbosity minimal — passed for net6.0, net8.0, and net10.0; 0 errors, 258 analyzer/documentation warnings in existing code.
  • git diff --check — passed.
  • dotnet format whitespace . --folder --include .\src\ExportHistory\Client\DefaultExportHistoryJobClient.cs .\test\ExportHistory.Tests\Client\DefaultExportHistoryJobClientTests.cs --verify-no-changes --verbosity minimal — reports only the existing FINALNEWLINE conflict: .editorconfig sets insert_final_newline = false, whereas StyleCop SA1518 requires a trailing newline. Both original files already have trailing newlines. Trailing newlines were retained rather than changing repository-wide configuration or adding SA1518 warnings; all other scoped whitespace checks are clean.
  • Whole-solution tests, service-backed E2E tests, and live DTS/production validation were not run.

Manual validation (only if runtime/behavior changed)

  • Environment (OS, .NET version, components): Windows, .NET SDK 10.0.403, actual DefaultExportHistoryJobClient exercised with Moq DurableTaskClient dependencies; no live service.
  • Steps + observed results:
    1. Hold the command-completion task pending: DeleteAsync stays incomplete and does not terminate/purge the linked orchestration. Complete that command successfully: linked termination, completion wait, and purge are each invoked once.
    2. Return Failed, Terminated, Pending, Running, or Suspended, or throw command-wait RPC NotFound/Unavailable: the error reaches the caller and linked cleanup is not started. The failure message is preserved when available.
    3. Cancel during the command-completion wait: cancellation reaches the caller without error logging or linked cleanup. A separate linked-orchestration NotFound after successful deletion still completes gracefully and skips purge.
  • Evidence (optional): The bounded unit tests above; no production validation or atomicity claim.

Notes for reviewers

  • Awaited entity deletion is separate from linked cleanup. Entity deletion must now be acknowledged successfully first. The existing linked orchestration termination/purge helper remains best-effort, and its error handling is unchanged. This does not make entity deletion plus orchestration cleanup atomic and does not add a sweeping service.
  • Waiting now depends on worker progress; callers can cancel the acknowledgement wait. Cancellation does not roll back an already-scheduled delete command. Existing cancellation behavior inside the separate linked-cleanup helper is unchanged.
  • Independent change based directly on main at f7041c032834ec72a1a3653803a58ab9fb354472; no dependency on the external-event lifetime or connection-diagnostics work. All 16 active PRs (including drafts) were rechecked for export-history file overlap before publication; none matched.

Wait for the entity deletion command to complete successfully before starting the existing best-effort linked orchestration cleanup. Propagate command failures and caller cancellation, with focused regression coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 5, 2026 14:24

Copilot AI 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.

🟢 Approval recommended

No active review issues remain for the changes that await delete-command completion before linked-orchestration cleanup.

No open issues 🎉

What changed in this PR

This PR makes the Export History client wait for the delete command to complete successfully before starting linked-orchestration cleanup, rather than treating command submission as completion.

Changes:

  • Await the delete command using its instance ID and the caller’s cancellation token.
  • Require Completed status and propagate failures through the existing logging and error-handling path.
  • Expand regression tests for ordering, unsuccessful statuses, RPC errors, cancellation, and graceful linked-orchestration NotFound handling.
File Description
test/​ExportHistory.Tests/​Client/​DefaultExportHistoryJobClientTests.cs Strengthens deletion tests to verify completion ordering, failure propagation, cancellation, and cleanup behavior.
src/​ExportHistory/​Client/​DefaultExportHistoryJobClient.cs Awaits and validates delete-command completion before linked-orchestration cleanup.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 23:17
@YunchuWang
wangbill (YunchuWang) merged commit 3612c73 into main Nov 5, 2026
9 of 10 checks passed
@YunchuWang
wangbill (YunchuWang) deleted the yunchuwang-export-deletion-acknowledgement branch November 5, 2026 23:19

Copilot AI 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.

🟢 Approval recommended

No active review issues are recorded for the change to await delete-command completion before linked-orchestration cleanup.

No open issues 🎉

Review effort: Balanced

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