Skip to content

fix: propagate async cancellation and await observer callbacks (#86) - #99

Draft
AGiorgetti wants to merge 3 commits into
developfrom
feature/fix-cancellation-propagation-86
Draft

AGiorgetti wants to merge 3 commits into
developfrom
feature/fix-cancellation-propagation-86

Conversation

@AGiorgetti

@AGiorgetti AGiorgetti commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Summary

Fixes #86.

  • Propagate OperationCanceledException (including TaskCanceledException) from ordinary Task/Task<T> operations instead of returning success with null/default values.
  • Let AddSnapshotAsync cancellation propagate while keeping its existing false result for non-cancellation failures.
  • Preserve the documented observer read contract: cancellation notifies and awaits OnCompletedAsync with the original request token. Normal completion is kept outside the operation guard, so a terminal callback's own cancellation/failure propagates without a second terminal notification.
  • Keep the protected virtual wrapper's normal-success behavior, synchronous paths, dependencies, and best-effort background work unchanged.

Tests first

The first commit contains only permanent regression tests against unchanged develop 286c0ae. With MongoDB 7.0.45 and .NET 10, its 167 focused checks produced 22 failures, 145 passes, 0 skips. The second commit fixes production code; all 167 focused checks pass.

The tests cover:

  • Public CommitAsync with a supported checkpoint generator, both cancellation exception types, pre-cancellation and a gated in-flight async boundary, canceled task state/token, and no write when cancellation occurs before persistence.
  • Both protected task wrappers; real-driver pre-canceled snapshot reads/writes, stream deletion, purge, bucket purge, and recycle-bin cleanup.
  • All seven observer read entrypoints, normal completion, pre-cancellation, two-record early termination, delayed cancellation, awaited completion/error callbacks, and terminal callback failures without duplicate notification.
  • Successful operations and unchanged sync/async null, absent, and invalid snapshot behavior.

The focused filter is FullyQualifiedName~Issue_86. Test-first and fix commits are separate; this branch contains no changes from the #87 or #85 PRs.

Local validation

Full Release solution build: 0 errors, including compilation of net472, net8.0, net9.0, and net10.0. Existing analyzer/dependency warnings remain; no dependency upgrades.

On each of .NET 8, 9, and 10 with MongoDB 7.0.45:

  • Focused regressions: 167 passed, 0 failed, 0 skipped.
  • Full adapter suite: 386 passed, 1 known baseline failure, 0 skipped.
  • Core suite: 536 passed, 0 failed, 0 skipped.

The sole local adapter failure is the pre-existing #94 IDHACK query-plan portability assertion, Stream_head_delete_by_id_should_use_the_builtin_id_index. It is unchanged and is not fixed or weakened here.

Contract and validation boundaries

Observer reads intentionally differ from ordinary task operations: their existing interface contract treats read cancellation as completion. That completion callback is now awaited; if it cancels or fails, the returned task reflects that outcome.

Cancellation after a server write is not a rollback guarantee. The deterministic in-flight tests cancel at supported checkpoint/callback async boundaries, not by interrupting a live network packet or server command. Real MongoDB I/O is covered by pre-canceled public operations and successful reads/writes.

Local MongoDB 8 cannot start in this cloud host because required /sys CPU metadata is unavailable, so local integration tests use MongoDB 7.0.45. The existing GitHub Actions matrix uses MongoDB 8; its verified result is recorded below. net472 is compile-only locally on Linux. No timing benchmarks were run.

Exact-head GitHub CI

CI run 39972739691 succeeded for head 79c751ccd9ca2eda614aa007bf6788e5aa862091. Ubuntu and Windows builds succeeded, and each MongoDB 8 Linux test job (.NET 8, 9, and 10) passed 387 tests, 0 failures, 0 skips, verified in the individual job logs. The PR workflow tested its merge with unchanged develop 286c0ae. No rerun was needed.

Draft for user review. This is the third and final fix in the requested batch; no merge or package publication is part of this task.

Co-authored by Alessandro Giorgetti and Codex (OpenAI).

Co-authored by Alessandro Giorgetti and Codex (OpenAI).
Co-authored by Alessandro Giorgetti and Codex (OpenAI).
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.

[P2] Task cancellation is swallowed and CommitAsync completes successfully with null

1 participant