Skip to content

feat: restart react frontend on backend foreground service crash - #271

Open
RangerMauve wants to merge 9 commits into
mainfrom
feat/restart-on-backend-crash
Open

feat: restart react frontend on backend foreground service crash#271
RangerMauve wants to merge 9 commits into
mainfrom
feat/restart-on-backend-crash

Conversation

@RangerMauve

@RangerMauve RangerMauve commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

part of #247

  • restart frontend on bg failure using a new dependency
  • maestro test for the new functionality

This lets us avoid funky resubscribe logic in our RPC layer for the edge case of Android killing the FGS on OOM (which is less likely to happen now that we have master key caching)

When the embedded backend (the :ComapeoCore foreground service) is killed
and cold-restarts, the @comapeo/ipc client in the React Native layer stays
bound to the dead transport: the socket reconnects, but the client's
subscription/correlation state is not rebuilt against the fresh backend.

Detect that loss->ready transition in the main process and restart the
React Native frontend via ProcessPhoenix, so the client and all JS state
are rebuilt against the fresh backend. The FGS runs in a separate process,
so it survives the restart and the relaunched app reconnects to it.

ProcessPhoenix (com.jakewharton:process-phoenix) is used directly rather
than via react-native-restart: the Android restart is just its
ProcessPhoenix.triggerRebirth() static call, so no JS/codegen layer is
pulled in.
Adds a Maestro flow that exercises the Android frontend-restart path: the
:ComapeoCore FGS is killed (and cold-restarts via START_STICKY) while the
React Native process stays alive, and the flow asserts the frontend restarts.

- New SIMULATE_PROCESS_KILL test seam: the FGS kills its own process without
  stopSelf so START_STICKY cold-restarts it; gated to the e2e app package so
  it stays inert in production.
- crashBackendForTesting() module fn + a "Crash backend (test)" button in the
  e2e app drive the seam.
- fresh-launch indicator (visible ~10s on each JS process) is the signal that
  the frontend actually restarted, not just the backend recovering.
- Flow is androidOnly (no-op on iOS, where Node is in-process) and is wired
  into the CI BrowserStack suite.
@RangerMauve RangerMauve self-assigned this Sep 8, 2026
@RangerMauve RangerMauve changed the title Feat/restart on backend crash feat: restart react frontend on backend foreground service crash Sep 8, 2026
@github-actions github-actions Bot added the feature New feature (changelog) label Sep 8, 2026
@RangerMauve
RangerMauve requested a review from cimigree September 8, 2026 15:40

@gmaclennan gmaclennan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

reviewed the wrong PR, oops!

Comment thread maestro/fgs-restart-frontend.yaml Outdated
`appContext` is Expo's AppContext, not an android.content.Context, so
`Intent(appContext, ...)`, `appContext.startForegroundService(...)`, and
`ProcessPhoenix.triggerRebirth(appContext)` did not compile. Switch both
call sites (restartFrontend + crashBackendForTesting) to
`appContext.reactContext` with a null guard, matching the pattern the
rest of the module already uses.

Verified locally: `:comapeo-core-react-native:testDebugUnitTest` compiles
and passes (161 tests, 0 failures).
@RangerMauve RangerMauve added the run-e2e Run the full BrowserStack e2e on this PR (otherwise it runs only in the merge queue) label Sep 9, 2026
@RangerMauve

Copy link
Copy Markdown
Contributor Author

Any clue why we're getting maestro parsing errors in the workflow?

@RangerMauve

Copy link
Copy Markdown
Contributor Author

turns out the agent just made up the "androidOnly" flag. took way too long to figure that out :P

`sleep` is not a valid Maestro command (2.7.0), which broke
BrowserStack's test-suite parse. The bg->fg round-trip plus the
extendedWaitUntil timeouts already provide the settle.
Wraps 'maestro check-syntax' across every maestro/*.yaml and exits non-zero
on failure. Catches unknown commands (e.g. a stray 'sleep') locally before
they surface in CI as an opaque BROWSERSTACK_TESTSUITE_PARSE_ERROR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature (changelog) run-e2e Run the full BrowserStack e2e on this PR (otherwise it runs only in the merge queue)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants