From e41f871c7d6389c9721c90c7781fd9354025f806 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Mon, 22 May 2023 09:12:49 -0700 Subject: [PATCH] Make sure the Native RuntimeScheduler is initialized on Old Arch (#37517) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37517 Fixes #35778 We got reports of regressions on `useEffect` starting from 0.69+ when on Hermes. The issue seems to be caused by a bump of the `scheduler` package from 0.20 to 0.21. In scheduler@0.21, the method `setImmediate` gets called if available (see https://github.com/facebook/react/pull/20834). This causes React Native to use Microtasks which ends up in changing the semantic of useEffect. The solution is to use the Native RuntimeScheduler properly. On Paper specifically, we never initialized it as it's effectively initialized by the TurboModuleManagerDelegate. Here I trigger the initialization of it on Paper as well. Changelog: [Android] [Fixed] - Make sure the Native RuntimeScheduler is initialized on Old Arch Reviewed By: sammy-SC Differential Revision: D46024807 fbshipit-source-id: da117769aaa60d1048e6ec50503c74eed6a0df3e --- .../java/com/facebook/react/ReactInstanceManager.java | 9 +++++++++ .../com/facebook/react/config/ReactFeatureFlags.java | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 53b8e507d4a79c..42e815bc6d8b5a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -1358,6 +1358,15 @@ private ReactApplicationContext createReactContext( reactContext.initializeWithInstance(catalystInstance); + if (ReactFeatureFlags.unstable_useRuntimeSchedulerAlways) { + // On Old Architecture, we need to initialize the Native Runtime Scheduler so that + // the `nativeRuntimeScheduler` object is registered on JS. + // On New Architecture, this is normally triggered by instantiate a TurboModuleManager. + // Here we invoke getRuntimeScheduler() to trigger the creation of it regardless of the + // architecture so it will always be there. + catalystInstance.getRuntimeScheduler(); + } + if (ReactFeatureFlags.useTurboModules && mTMMDelegateBuilder != null) { TurboModuleManagerDelegate tmmDelegate = mTMMDelegateBuilder diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 3ee102049179f2..c4f7ef5248cb2b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -50,6 +50,13 @@ public class ReactFeatureFlags { */ public static volatile boolean unstable_useFabricInterop = false; + /** + * Should this application always use the Native RuntimeScheduler? If yes, we'll be instantiating + * it over all the architectures (both Old and New). This is intentionally set to true as we want + * to use it more as a kill-switch to turn off this feature to potentially debug issues. + */ + public static volatile boolean unstable_useRuntimeSchedulerAlways = true; + /** * Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable * the following flags: `useTurboModules` & `enableFabricRenderer`.