Skip to content

Retry a failed notifyAppReady() on the next call - #106

Merged
ofalvai merged 1 commit into
masterfrom
retry-notify-application-ready
Nov 5, 2026
Merged

ofalvai merged 1 commit into
masterfrom
retry-notify-application-ready

Conversation

@ofalvai

@ofalvai ofalvai commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Background

notifyApplicationReady() is how the app tells CodePush that a freshly installed bundle booted fine. If native code doesn't hear it before the next launch, it assumes the update is broken and rolls it back. sync() also calls it first, before checking for updates.

The JS side memoized that call so native code is only asked once per app session. It memoized the promise, whatever the outcome.

Problem

If the native call fails once, for example on a transient bridge error at startup, the rejected promise stays cached. From then on:

  • Every sync() in that session fails immediately and never checks for updates.
  • Nothing ever tells native code the update is healthy, so a good update is rolled back on the next restart.

Change

Keep the memoization, but drop a rejected promise so the next caller tries again. Concurrent callers still share one in-flight call, and a success is still cached for the session. The helper is in src/ with unit tests, per the rule for new code.

Not covered

An app that calls notifyApplicationReady() once at startup and ignores the error still never retries. Only callers like sync() benefit. Having the SDK retry on its own would be a separate decision.

🤖 Generated with Claude Code

CodePush.js cached the promise of the first notifyAppReady() call, even
when it rejected. After a failure, every later notifyAppReady() and sync()
call failed the same way until the app restarted, and the update was rolled
back. The cache now keeps a pending or resolved promise only, so the next
caller tries again. A caller that ignores the promise still gets the
unhandled rejection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ofalvai ofalvai self-assigned this Nov 4, 2026
Copilot AI balanced review requested due to automatic review settings November 4, 2026 11:59

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.

🟢 Approval recommended

No active review issues remain for the change allowing notifyApplicationReady() to retry after a rejected attempt.

No open issues 🎉

What changed in this PR

Fixes permanently cached failures in notifyApplicationReady(), allowing a later call to retry instead of leaving a healthy update vulnerable to rollback.

Changes:

  • Adds a TypeScript helper that clears rejected attempts while sharing pending calls and caching success.
  • Applies the helper to notifyApplicationReady() without changing rejection propagation.
  • Adds unit tests for deduplication, retry after rejection, and success caching.
File Description
src/​once-until-rejected.ts Implements promise caching that resets after rejection.
src/​__tests__/​once-until-rejected.test.ts Tests shared pending calls, retries, and cached success.
CodePush.js Replaces permanent promise caching with the new helper.

Review effort: Balanced

@ofalvai ofalvai mentioned this pull request Nov 4, 2026
@ofalvai
ofalvai merged commit be068e9 into master Nov 5, 2026
7 checks passed
@ofalvai
ofalvai deleted the retry-notify-application-ready branch November 5, 2026 09:31
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.

3 participants