Preserve coroutine cancellation through framework cleanup and I/O

Merged
BI
1d ago
+2779-488

Cancellation could be lost when an application callback, stream producer or cleanup operation threw another exception. That could allow retries or fallback work to continue after cancellation, or leave owned resources unreleased.

This change preserves cancellation through framework cleanup and I/O:

  • Recognize cancellation through exception chains and apply consistent precedence when cleanup also fails, while respecting independent child and foreign-owner failures.
  • Stop canceled cache, authentication, session, batch, notification and other callback-driven operations at their existing owning boundaries.
  • Preserve cancellation through pooled database and Redis cleanup, process teardown, and filesystem reads and writes.
  • Add a PSR stream resource bridge that propagates cancellation and preserves borrowed versus owned stream lifetimes, retaining the native-stream fast path.

Regression coverage checks direct and wrapped cancellation, ordinary-error handling, resource cleanup and callback behavior. It also records the Google SDK's existing loss of exception causes during resumable uploads with a skipped regression pending a dependency fix.

Targeted source analysis, formatting and affected tests pass. The full suite and service matrices run in CI.


Summary by cubic

Preserves coroutine cancellation through framework cleanup and I/O so canceled operations stop retries, fallback work, and resource release instead of being treated as ordinary failures.

  • Recognizes cancellation through exception chains, including Google's separately stored service causes, and gives it precedence over ordinary cleanup failures while respecting foreign and child coroutine boundaries.
  • Stops canceled cache, auth, session, batch, notification, and other callback-driven operations at their owning boundaries; cache serialization policy now finalizes in custom server processes too.
  • Preserves cancellation through pooled database and Redis cleanup, process teardown, and filesystem reads and writes, including file lock owner deserialization.
  • Adds a PSR stream resource bridge that propagates cancellation, distinguishes borrowed from owned streams, and exposes descriptors only for exact native Guzzle streams while keeping decorated streams usable.
  • Adds regression coverage for direct and wrapped cancellation, cleanup, and callback behavior; records Google SDK's loss of exception causes in resumable uploads with a skipped regression pending a dependency fix.

[!NOTE]

Preserve wrapped coroutine cancellation through framework cleanup and I/O

  • Adds Coroutine::causedByCancellation and Coroutine::preferCancellation in Coroutine.php. The detector now walks exception cause chains (including Google Cloud ServiceException), and the precedence helper prefers a cancellation-caused failure over a previously kept ordinary failure.
  • Applies these helpers across cache, filesystem, Redis, bus, process, view, socialite, validation, session, pennant, passport, and support code. Wrapped cancellation exceptions are now rethrown or propagate instead of being swallowed by fallback paths, and failure events like KeyRetrievalFailed are no longer dispatched for cancellation-caused errors.
  • Adds StreamWrapper in StreamWrapper.php, a PHP stream-wrapper adapter for PSR-7 streams with borrowed and owned resource paths. FilesystemAdapter and the S3/Google Cloud adapters use it for stream reads/writes and now rethrow cancellation-caused failures even under a non-throwing failure policy.
  • Cache serializable classes now finalize on BeforeProcessHandle as well as AfterWorkerStart in CacheServiceProvider.php, covering custom server processes. Several packages add hypervel/coroutine ^0.4 as a dependency.
  • Behavioral Change: code that previously suppressed, reported, or converted cancellation exceptions now rethrows them — see Str string conversion, Timebox::call, StdoutLogger encoding, SafeCaller, and NotPwnedVerifier. Cache reads with cancellation during unserialization no longer delete the cached key.

Macroscope summarized 9995a29.

Summary by CodeRabbit

  • New Features
    • Added reusable stream-resource support for HTTP and filesystem operations, with improved stream ownership and cleanup.
    • Expanded coroutine cancellation handling across storage, queues, processes, notifications, and other operations, including wrapped cancellations.
    • Cancellation is prioritized appropriately when an operation and its cleanup both fail.
  • Bug Fixes
    • Cancellation errors propagate instead of being swallowed, retried, reported as ordinary failures, or treated as successful validation.
    • Failure notifications and batch cleanup behave more consistently when operations fail.
  • Documentation
    • Documented cancellation precedence and when serializable cache classes are resolved in custom server processes.