Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auto-update): make bundle rollback more robust #502

Open
hakant opened this issue Dec 23, 2024 · 1 comment
Open

feat(auto-update): make bundle rollback more robust #502

hakant opened this issue Dec 23, 2024 · 1 comment

Comments

@hakant
Copy link

hakant commented Dec 23, 2024

Feature Request

Description

In auto-update scenarios, new bundles are often set while the app is running in the background. During this time, the JavaScript execution of the webview is usually deprioritized by the mobile operating system due to backgrounding. This leads to slow or delayed JavaScript execution, which in turn necessitates higher appReadyTimeout configurations (typically 10–20 seconds).

The issue with prolonged appReadyTimeout durations is that, if a bundle contains a bug causing a critical crash, recovery takes too long. In real-world usage, most users won’t wait 10–20 seconds staring at a white screen. Instead, they are likely to kill the app and give up, meaning recovery might never occur.

I propose two solutions to address this problem:

  1. Expose a plugin API that allows developers to programmatically change a bundle's status to an error state. This would enable developers to detect a critical crash, mark the bundle as erroneous, and reset to the last successful bundle without waiting for the appReadyTimeout. Resetting is already possible, but without marking the current bundle as erroneous it doesn't seem very useful as it locks up in a cycle of update -> fail -> reset.
  2. Introduce a configuration property that allows developers to disable setting new bundles while the app is in the background. New bundle activations would then only occur during app launches. Enforcing bundle activation when the app is in the foreground (e.g., after a launch) would make JavaScript execution more predictable and allow for reduced appReadyTimeout durations.

Platform(s)

iOS & Android

Preferred Solution

Both solutions 1 and 2 would be generally useful. If I had to prioritize, solution 1 would likely be sufficient. However, I’m uncertain if updating the bundle while the app (and therefore the webview) is in the background introduces other edge case consequences. For instance, if the webview receives no execution time, it might lead to false rollbacks.

Alternatives

An alternative would be to abandon auto-updates altogether and implement a custom manual update logic. However, this approach would sacrifice the auto-update feature's implicit disaster recovery benefit thanks to its native implementation, which is independent of JavaScript execution in the bundle. Losing this feature would be unfortunate.

Additional Context

Here’s some additional context: we’re aiming to move notifyAppReady to the end of the critical application load path, covering bundle startup and the display of the first screen. This process should take no more than 3–5 seconds. However, when the app is in the background, the mobile operating system may arbitrarily freeze JavaScript execution in the webview depending on device activity. This forces us to increase the timeout, ultimately reducing the effectiveness of recovery mechanisms.

Curious about your thoughts and whether there are any other solutions we might have missed in our analysis. Thank you!

@riderx
Copy link
Collaborator

riderx commented Dec 30, 2024

Hello thanks for the feedback, we just released a new Android version who use WorkerManager.
WorkerManager allows us to keep the app alive the time works happens.
It's currently used for download only but maybe we could extend it to "SET" method this would probably solve your issue?
on your point 1 you mean in JS in the app or in backend on your side with API to capgo ?
2. this option is requested since long but our current implementation doesn't allow us to do it easily

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

No branches or pull requests

2 participants