Skip to content

Commit 87c08df

Browse files
rubennortefacebook-github-bot
authored andcommitted
Wire up configuration to use modern version of RuntimeScheduler (#40945)
Summary: Pull Request resolved: #40945 This adds some temporary logic to configure the use of the modern version of RuntimeScheduler based on values coming from the app configuration. This logic is centralized in `ReactInstance` so from that point the code is completely cross-platform. This doesn't use `ReactNativeConfig`/`CoreFeatures` because they're initialized after the point where we need to access them for this use case. This way is a bit uglier but this isn't intended to live for long (only until we verify this doesn't have regressions in a complex app). Changelog: [internal] --- Reviewed By: sammy-SC Differential Revision: D50171297 fbshipit-source-id: 8d96e228550cc6112ffe2abec4d531514b052f82
1 parent 220dcde commit 87c08df

File tree

10 files changed

+74
-14
lines changed

10 files changed

+74
-14
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,10 @@ public class ReactFeatureFlags {
165165

166166
/** Enables Stable API for TurboModule (removal of ReactModule, ReactModuleInfoProvider). */
167167
public static boolean enableTurboModuleStableAPI = false;
168+
169+
/**
170+
* When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with
171+
* priorities from any thread.
172+
*/
173+
public static boolean useModernRuntimeScheduler = false;
168174
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ public void onHostDestroy() {
170170
// Notify JS if profiling is enabled
171171
boolean isProfiling =
172172
Systrace.isTracing(Systrace.TRACE_TAG_REACT_APPS | Systrace.TRACE_TAG_REACT_JS_VM_CALLS);
173+
// TODO(T166383606): Remove this parameter when we remove the legacy runtime scheduler or we
174+
// have access to ReactNativeConfig before we initialize it.
175+
boolean useModernRuntimeScheduler = ReactFeatureFlags.useModernRuntimeScheduler;
173176
mHybridData =
174177
initHybrid(
175178
jsEngineInstance,
@@ -179,7 +182,8 @@ public void onHostDestroy() {
179182
jsTimerExecutor,
180183
reactExceptionManager,
181184
bindingsInstaller,
182-
isProfiling);
185+
isProfiling,
186+
useModernRuntimeScheduler);
183187

184188
RuntimeExecutor unbufferedRuntimeExecutor = getUnbufferedRuntimeExecutor();
185189

@@ -435,7 +439,8 @@ private native HybridData initHybrid(
435439
JSTimerExecutor jsTimerExecutor,
436440
ReactJsExceptionHandler jReactExceptionsManager,
437441
@Nullable BindingsInstaller jBindingsInstaller,
438-
boolean isProfiling);
442+
boolean isProfiling,
443+
boolean useModernRuntimeScheduler);
439444

440445
@DoNotStrip
441446
private static native JSTimerExecutor createJSTimerExecutor();

packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ JReactInstance::JReactInstance(
3636
jni::alias_ref<JJSTimerExecutor::javaobject> jsTimerExecutor,
3737
jni::alias_ref<JReactExceptionManager::javaobject> jReactExceptionManager,
3838
jni::alias_ref<JBindingsInstaller::javaobject> jBindingsInstaller,
39-
bool isProfiling) noexcept {
39+
bool isProfiling,
40+
bool useModernRuntimeScheduler) noexcept {
4041
// TODO(janzer): Lazily create runtime
4142
auto sharedJSMessageQueueThread =
4243
std::make_shared<JMessageQueueThread>(jsMessageQueueThread);
@@ -64,7 +65,8 @@ JReactInstance::JReactInstance(
6465
jsEngineInstance->cthis()->createJSRuntime(sharedJSMessageQueueThread),
6566
sharedJSMessageQueueThread,
6667
timerManager,
67-
std::move(jsErrorHandlingFunc));
68+
std::move(jsErrorHandlingFunc),
69+
useModernRuntimeScheduler);
6870

6971
auto bufferedRuntimeExecutor = instance_->getBufferedRuntimeExecutor();
7072
timerManager->setRuntimeExecutor(bufferedRuntimeExecutor);
@@ -115,7 +117,8 @@ jni::local_ref<JReactInstance::jhybriddata> JReactInstance::initHybrid(
115117
jni::alias_ref<JJSTimerExecutor::javaobject> jsTimerExecutor,
116118
jni::alias_ref<JReactExceptionManager::javaobject> jReactExceptionManager,
117119
jni::alias_ref<JBindingsInstaller::javaobject> jBindingsInstaller,
118-
bool isProfiling) {
120+
bool isProfiling,
121+
bool useModernRuntimeScheduler) {
119122
return makeCxxInstance(
120123
jsEngineInstance,
121124
jsMessageQueueThread,
@@ -124,7 +127,8 @@ jni::local_ref<JReactInstance::jhybriddata> JReactInstance::initHybrid(
124127
jsTimerExecutor,
125128
jReactExceptionManager,
126129
jBindingsInstaller,
127-
isProfiling);
130+
isProfiling,
131+
useModernRuntimeScheduler);
128132
}
129133

130134
void JReactInstance::loadJSBundleFromAssets(

packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ class JReactInstance : public jni::HybridClass<JReactInstance> {
4545
jni::alias_ref<JJSTimerExecutor::javaobject> jsTimerExecutor,
4646
jni::alias_ref<JReactExceptionManager::javaobject> jReactExceptionManager,
4747
jni::alias_ref<JBindingsInstaller::javaobject> jBindingsInstaller,
48-
bool isProfiling);
48+
bool isProfiling,
49+
bool useModernRuntimeScheduler);
4950

5051
/*
5152
* Instantiates and returns an instance of `JSTimerExecutor`.
@@ -90,7 +91,8 @@ class JReactInstance : public jni::HybridClass<JReactInstance> {
9091
jni::alias_ref<JJSTimerExecutor::javaobject> jsTimerExecutor,
9192
jni::alias_ref<JReactExceptionManager::javaobject> jReactExceptionManager,
9293
jni::alias_ref<JBindingsInstaller::javaobject> jBindingsInstaller,
93-
bool isProfiling) noexcept;
94+
bool isProfiling,
95+
bool useModernRuntimeScheduler) noexcept;
9496

9597
jni::alias_ref<CallInvokerHolder::javaobject> getJSCallInvokerHolder();
9698
jni::alias_ref<NativeMethodCallInvokerHolder::javaobject>

packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ ReactInstance::ReactInstance(
2828
std::unique_ptr<jsi::Runtime> runtime,
2929
std::shared_ptr<MessageQueueThread> jsMessageQueueThread,
3030
std::shared_ptr<TimerManager> timerManager,
31-
JsErrorHandler::JsErrorHandlingFunc jsErrorHandlingFunc)
31+
JsErrorHandler::JsErrorHandlingFunc jsErrorHandlingFunc,
32+
bool useModernRuntimeScheduler)
3233
: runtime_(std::move(runtime)),
3334
jsMessageQueueThread_(jsMessageQueueThread),
3435
timerManager_(std::move(timerManager)),
@@ -75,8 +76,8 @@ ReactInstance::ReactInstance(
7576
}
7677
};
7778

78-
runtimeScheduler_ =
79-
std::make_shared<RuntimeScheduler>(std::move(runtimeExecutor));
79+
runtimeScheduler_ = std::make_shared<RuntimeScheduler>(
80+
std::move(runtimeExecutor), useModernRuntimeScheduler);
8081

8182
auto pipedRuntimeExecutor =
8283
[runtimeScheduler = runtimeScheduler_.get()](

packages/react-native/ReactCommon/react/runtime/ReactInstance.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class ReactInstance final {
3232
std::unique_ptr<jsi::Runtime> runtime,
3333
std::shared_ptr<MessageQueueThread> jsMessageQueueThread,
3434
std::shared_ptr<TimerManager> timerManager,
35-
JsErrorHandler::JsErrorHandlingFunc JsErrorHandlingFunc);
35+
JsErrorHandler::JsErrorHandlingFunc JsErrorHandlingFunc,
36+
bool useModernRuntimeScheduler = false);
3637

3738
RuntimeExecutor getUnbufferedRuntimeExecutor() noexcept;
3839

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ NS_ASSUME_NONNULL_BEGIN
3535

3636
@end
3737

38+
/**
39+
* This is a private protocol used to configure internal behavior of the runtime.
40+
* DO NOT USE THIS OUTSIDE OF THE REACT NATIVE CODEBASE.
41+
*/
42+
@protocol RCTHostDelegateInternal <NSObject>
43+
44+
// TODO(T166383606): Remove this method when we remove the legacy runtime scheduler or we have access to
45+
// ReactNativeConfig before we initialize it.
46+
- (BOOL)useModernRuntimeScheduler:(RCTHost *)host;
47+
48+
@end
49+
3850
@protocol RCTHostRuntimeDelegate <NSObject>
3951

4052
- (void)host:(RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtime &)runtime;

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
using namespace facebook::react;
2525

26-
@interface RCTHost () <RCTReloadListener, RCTInstanceDelegate>
26+
@interface RCTHost () <RCTReloadListener, RCTInstanceDelegate, RCTInstanceDelegateInternal>
2727
@end
2828

2929
@implementation RCTHost {
@@ -247,6 +247,17 @@ - (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Ru
247247
[self.runtimeDelegate host:self didInitializeRuntime:runtime];
248248
}
249249

250+
#pragma mark - RCTInstanceDelegateInternal
251+
252+
- (BOOL)useModernRuntimeScheduler:(RCTHost *)host
253+
{
254+
if ([_hostDelegate respondsToSelector:@selector(useModernRuntimeScheduler:)]) {
255+
return [(id)_hostDelegate useModernRuntimeScheduler:self];
256+
}
257+
258+
return NO;
259+
}
260+
250261
#pragma mark - RCTContextContainerHandling
251262

252263
- (void)didCreateContextContainer:(std::shared_ptr<facebook::react::ContextContainer>)contextContainer

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
4646

4747
@end
4848

49+
/**
50+
* This is a private protocol used to configure internal behavior of the runtime.
51+
* DO NOT USE THIS OUTSIDE OF THE REACT NATIVE CODEBASE.
52+
*/
53+
@protocol RCTInstanceDelegateInternal <NSObject>
54+
55+
// TODO(T166383606): Remove this method when we remove the legacy runtime scheduler or we have access to
56+
// ReactNativeConfig before we initialize it.
57+
- (BOOL)useModernRuntimeScheduler:(RCTInstance *)instance;
58+
59+
@end
60+
4961
typedef void (^_Null_unspecified RCTInstanceInitialBundleLoadCompletionBlock)();
5062

5163
/**

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,18 @@ - (void)_start
216216
__weak __typeof(self) weakSelf = self;
217217
auto jsErrorHandlingFunc = [=](MapBuffer errorMap) { [weakSelf _handleJSErrorMap:std::move(errorMap)]; };
218218

219+
auto useModernRuntimeScheduler = false;
220+
if ([_delegate respondsToSelector:@selector(useModernRuntimeScheduler:)]) {
221+
useModernRuntimeScheduler = [(id)_delegate useModernRuntimeScheduler:self];
222+
}
223+
219224
// Create the React Instance
220225
_reactInstance = std::make_unique<ReactInstance>(
221226
_jsEngineInstance->createJSRuntime(_jsThreadManager.jsMessageThread),
222227
_jsThreadManager.jsMessageThread,
223228
timerManager,
224-
jsErrorHandlingFunc);
229+
jsErrorHandlingFunc,
230+
useModernRuntimeScheduler);
225231
_valid = true;
226232

227233
RuntimeExecutor bufferedRuntimeExecutor = _reactInstance->getBufferedRuntimeExecutor();

0 commit comments

Comments
 (0)