Skip to content

fix(core): add timeout to BackgroundProcessManager.close()#14719

Open
anivar wants to merge 1 commit intoaws-amplify:mainfrom
anivar:fix/background-process-manager-close-timeout
Open

fix(core): add timeout to BackgroundProcessManager.close()#14719
anivar wants to merge 1 commit intoaws-amplify:mainfrom
anivar:fix/background-process-manager-close-timeout

Conversation

@anivar
Copy link
Contributor

@anivar anivar commented Feb 17, 2026

We've been hitting a persistent issue where DataStore gets permanently stuck in "Stopping" state after network drops. Once stuck, every save/query/start throws DataStoreStateError and only an app restart recovers. This is a real problem for our offline-first POS app where network is unreliable.

Traced it down to BackgroundProcessManager.close() — it awaits Promise.allSettled(jobs) with no timeout. The subscription processor never implements the onTerminate handler (there's a TODO at subscription.ts:411), so when network is down those jobs just hang forever. close() never returns, DataStore never transitions out of Stopping.

Related: #13035 #10612 #12359

The fix is small — race _closingPromise against a 10s timeout so close() always resolves. One subtlety: close() is async and ends with return this._closingPromise, which in an async function adopts the promise state. So even if you raced past the await, the return would re-block callers on the original never-settling allSettled. Fixed by reassigning _closingPromise to the race result.

After timeout, zombie jobs stay in the Set but self-clean via the existing .then() in registerPromise when they eventually resolve. This matches what the community has been doing as app-layer workarounds (see #10612).

Ideally the subscription/sync processors would implement onTerminate properly, but that's a bigger change across multiple files. This at least unblocks the stop/start cycle.

close() hangs forever when jobs depend on unavailable resources
(e.g. network down during DataStore subscription teardown).

Race _closingPromise against a 10s timeout so it always resolves.
@anivar anivar requested a review from a team as a code owner February 17, 2026 12:23
@changeset-bot
Copy link

changeset-bot bot commented Feb 17, 2026

⚠️ No Changeset found

Latest commit: a39a1f8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

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.

1 participant

Comments