Skip to content

fix: own a DI scope per fire-and-forget handover push send - #1669

Merged
renemadsen merged 2 commits into
stablefrom
feat/push-scope-fix
Aug 2, 2026
Merged

fix: own a DI scope per fire-and-forget handover push send#1669
renemadsen merged 2 commits into
stablefrom
feat/push-scope-fix

Conversation

@renemadsen

Copy link
Copy Markdown
Member

Fixes the live ObjectDisposedException on tenant 855: the three fire-and-forget handover push sends captured the request-scoped IPushNotificationService/DbContext, which was disposed when the gRPC request completed. Each send now creates and owns its scope via IServiceScopeFactory; the two silent-skip log lines are elevated to Information; four regression tests pin the contract.

Spec: flutter-adhoc/docs/superpowers/specs/2026-08-02-flutter-time-push-fixes-design.md

🤖 Generated with Claude Code

renemadsen and others added 2 commits August 2, 2026 07:29
The three fire-and-forget push sends captured the request-scoped
IPushNotificationService/DbContext; after the gRPC request completed the
scope was disposed and SendToSiteAsync threw ObjectDisposedException
(live-verified on tenant 855). Each send now runs in its own scope via
IServiceScopeFactory. Also elevates the two silent-skip log lines to
Information so skipped sends are visible at default log level.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four regression tests inside ContentHandoverServiceTests (CI shard
allowlist) pinning: push service resolved from an owned scope which is
disposed after the send; accept/reject payloads target the requester;
push failures are swallowed with the scope still disposed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@renemadsen
renemadsen marked this pull request as ready for review August 2, 2026 07:01
Copilot AI review requested due to automatic review settings August 2, 2026 07:01
@renemadsen
renemadsen merged commit 33be1a7 into stable Aug 2, 2026
39 checks passed
@renemadsen
renemadsen deleted the feat/push-scope-fix branch August 2, 2026 07:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Fixes a production ObjectDisposedException by ensuring the handover-related fire-and-forget push notifications do not capture request-scoped services (e.g., IPushNotificationService/DbContext) after the gRPC request completes. Instead, each background send now creates and disposes its own DI scope.

Changes:

  • Refactors ContentHandoverService to resolve IPushNotificationService from a new scope per push-send using IServiceScopeFactory, and routes the three fire-and-forget sends through scope-owning async methods.
  • Elevates two “silent skip” push-notification log messages from Debug to Information.
  • Updates and adds regression tests to validate the scope-owning push-send contract and disposal behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/PushNotificationService/PushNotificationService.cs Promotes push-skip logs (Firebase not configured / no tokens) to Information for improved visibility.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/ContentHandoverService/ContentHandoverService.cs Avoids capturing request-scoped services by creating an owned DI scope per background push send via IServiceScopeFactory.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/PushNotificationIntegrationTests.cs Updates test wiring for ContentHandoverService constructor change (scope factory instead of direct push service).
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/ContentHandoverServiceTests.cs Adds regression tests that assert push sends resolve from an owned scope and that the scope is disposed even on failure.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/ContentHandoverRemovedRowTests.cs Updates test wiring for the new ContentHandoverService constructor dependency (scope factory).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants