-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
introduce native api to access RuntimeExecutor #42882
Conversation
This pull request was exported from Phabricator. Differential Revision: D53461821 |
Summary: Changelog: [Android][Added] - introduce native api to access RuntimeExecutor This is the android equivalent of [PR#42758](facebook#42758). From [PR#42758](facebook#42758) > The goal of this API is to provide a safe way to access the jsi::runtime in bridgeless mode. The decision to limit access to the runtime in bridgeless was a conscious one - the runtime pointer is not thread-safe and its lifecycle must be managed correctly by owners. > However, interacting with the runtime is an advanced use case we would want to support. Our recommended ways to access the runtime in bridgeless mode is either 1) via the RuntimeExecutor, or 2) via a C++ TurboModule. This diff introduces the API that would allow for 1). because react context can be non-null before react instance is ready, i created an async api that will guarantee the runtime executor will be ready. Differential Revision: D53461821
d29b833
to
bb2ee82
Compare
This pull request was exported from Phabricator. Differential Revision: D53461821 |
Base commit: e37da1e |
|
||
reactContext.executeRuntimeExecutor( | ||
new ReactContext.ReactRuntimeExecutor() { | ||
@Override | ||
public void execute(RuntimeExecutor runtimeExecutor) { | ||
// do something | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reactContext.executeRuntimeExecutor( | |
new ReactContext.ReactRuntimeExecutor() { | |
@Override | |
public void execute(RuntimeExecutor runtimeExecutor) { | |
// do something | |
} | |
}); |
It doesn't do anything 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh whoops this was my testing code hehe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use a different module for this test.
At meta: FrescoModule is eagerly initialized when the ReactInstance is created.
So when this initialize method is executed, the ReactContext and the ReactHost don't have access to the ReactInstance reference (and hence the runtime executor reference), because it's being created.
That's probably why you had to create an async api to access the RuntimeExecutor?
void executeRuntimeExecutor(ReactRuntimeExecutor reactRuntimeExecutor) { | ||
mReactInstanceTaskRef | ||
.get() | ||
.onSuccess( | ||
task -> { | ||
final ReactInstance reactInstance = task.getResult(); | ||
if (reactInstance == null) { | ||
return false; | ||
} | ||
reactRuntimeExecutor.execute(reactInstance.getBufferedRuntimeExecutor()); | ||
return true; | ||
}, | ||
mBGExecutor); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Access to the runtime executer will be obtained asynchronously. Currently, in our flow, module initialization starts when native constants are received. It is uncertain whether this will be invoked in time before the JS continues executing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lukmccall, the code is very different now.
NativeModules can now access the runtime by calling ReactContext.getRuntimeExecutor().
This method should work for all cases except for this one: when ReactHost's ReactInstance is/becomes null.
This happens in two scenarios:
- The native module is created eagerly (i.e: while ReactHost is creating the ReactInstance).
- The native module outlives the ReactInstance (i.e: ReactHost kills the ReactInstance, but something else keeps the native module alive).
Aside from that, I think the concern you mentioned about timing still exists.
I talked with Phillip offline: Maybe we could continue with this solution for now, and iterate on it, if we see any problems? I think we want to replace this solution with something more reliable down the line anyway.
void executeRuntimeExecutor(ReactRuntimeExecutor reactRuntimeExecutor) { | ||
mReactInstanceTaskRef | ||
.get() | ||
.onSuccess( | ||
task -> { | ||
final ReactInstance reactInstance = task.getResult(); | ||
if (reactInstance == null) { | ||
return false; | ||
} | ||
reactRuntimeExecutor.execute(reactInstance.getBufferedRuntimeExecutor()); | ||
return true; | ||
}, | ||
mBGExecutor); | ||
} | ||
|
||
/* package */ | ||
@Nullable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void executeRuntimeExecutor(ReactRuntimeExecutor reactRuntimeExecutor) { | |
mReactInstanceTaskRef | |
.get() | |
.onSuccess( | |
task -> { | |
final ReactInstance reactInstance = task.getResult(); | |
if (reactInstance == null) { | |
return false; | |
} | |
reactRuntimeExecutor.execute(reactInstance.getBufferedRuntimeExecutor()); | |
return true; | |
}, | |
mBGExecutor); | |
} | |
/* package */ | |
@Nullable | |
@Deprecated | |
RuntimeExecutor getRuntimeExecutor() { | |
return mReactInstanceTaskRef.get().getResult().getBufferedRuntimeExecutor(); | |
} | |
/* package */ | |
@Nullable |
@Override | ||
public void executeRuntimeExecutor(ReactRuntimeExecutor runtimeExecutor) { | ||
mReactHost.executeRuntimeExecutor(runtimeExecutor); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Override | |
public void executeRuntimeExecutor(ReactRuntimeExecutor runtimeExecutor) { | |
mReactHost.executeRuntimeExecutor(runtimeExecutor); | |
} | |
@Override | |
public RuntimeExecutor getRuntimeExecutor() { | |
return mReactHost.getRuntimeExecutor(); | |
} | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea this was my first version but i ran into the issue with FrescoModule T_T but what you're saying for needsEagerInit for the FrescoModule makes sense
|
||
reactContext.executeRuntimeExecutor( | ||
new ReactContext.ReactRuntimeExecutor() { | ||
@Override | ||
public void execute(RuntimeExecutor runtimeExecutor) { | ||
// do something | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use a different module for this test.
At meta: FrescoModule is eagerly initialized when the ReactInstance is created.
So when this initialize method is executed, the ReactContext and the ReactHost don't have access to the ReactInstance reference (and hence the runtime executor reference), because it's being created.
That's probably why you had to create an async api to access the RuntimeExecutor?
bb2ee82
to
27c3fe2
Compare
Summary: Changelog: [Android][Added] - introduce native api to access RuntimeExecutor This is the android equivalent of [PR#42758](facebook#42758). From [PR#42758](facebook#42758) > The goal of this API is to provide a safe way to access the jsi::runtime in bridgeless mode. The decision to limit access to the runtime in bridgeless was a conscious one - the runtime pointer is not thread-safe and its lifecycle must be managed correctly by owners. > However, interacting with the runtime is an advanced use case we would want to support. Our recommended ways to access the runtime in bridgeless mode is either 1) via the RuntimeExecutor, or 2) via a C++ TurboModule. This diff introduces the API that would allow for 1). because react context can be non-null before react instance is ready, i created an async api that will guarantee the runtime executor will be ready. Differential Revision: D53461821
This pull request was exported from Phabricator. Differential Revision: D53461821 |
Summary: Changelog: [Android][Added] - introduce native api to access RuntimeExecutor This is the android equivalent of [PR#42758](facebook#42758). From [PR#42758](facebook#42758) > The goal of this API is to provide a safe way to access the jsi::runtime in bridgeless mode. The decision to limit access to the runtime in bridgeless was a conscious one - the runtime pointer is not thread-safe and its lifecycle must be managed correctly by owners. > However, interacting with the runtime is an advanced use case we would want to support. Our recommended ways to access the runtime in bridgeless mode is either 1) via the RuntimeExecutor, or 2) via a C++ TurboModule. This diff introduces the API that would allow for 1). because react context can be non-null before react instance is ready, this can still return null. however, the callsite should be cognizant of when this will happen. in the case of expomodules, the runtime should be ready when the module is init, unless it is a eager initialized module Differential Revision: D53461821
27c3fe2
to
bf10b63
Compare
This pull request was exported from Phabricator. Differential Revision: D53461821 |
Summary: Changelog: [Android][Added] - introduce native api to access RuntimeExecutor This is the android equivalent of [PR#42758](facebook#42758). From [PR#42758](facebook#42758) > The goal of this API is to provide a safe way to access the jsi::runtime in bridgeless mode. The decision to limit access to the runtime in bridgeless was a conscious one - the runtime pointer is not thread-safe and its lifecycle must be managed correctly by owners. > However, interacting with the runtime is an advanced use case we would want to support. Our recommended ways to access the runtime in bridgeless mode is either 1) via the RuntimeExecutor, or 2) via a C++ TurboModule. This diff introduces the API that would allow for 1). because react context can be non-null before react instance is ready, this can still return null. however, the callsite should be cognizant of when this will happen. in the case of expomodules, the runtime should be ready when the module is init, unless it is a eager initialized module Differential Revision: D53461821
bf10b63
to
cf3ea88
Compare
This pull request was exported from Phabricator. Differential Revision: D53461821 |
Summary: Changelog: [Android][Added] - introduce native api to access RuntimeExecutor This is the android equivalent of [PR#42758](facebook#42758). From [PR#42758](facebook#42758) > The goal of this API is to provide a safe way to access the jsi::runtime in bridgeless mode. The decision to limit access to the runtime in bridgeless was a conscious one - the runtime pointer is not thread-safe and its lifecycle must be managed correctly by owners. > However, interacting with the runtime is an advanced use case we would want to support. Our recommended ways to access the runtime in bridgeless mode is either 1) via the RuntimeExecutor, or 2) via a C++ TurboModule. This diff introduces the API that would allow for 1). because react context can be non-null before react instance is ready, this can still return null. however, the callsite should be cognizant of when this will happen. in the case of expomodules, the runtime should be ready when the module is init, unless it is a eager initialized module Differential Revision: D53461821
cf3ea88
to
ff47c1b
Compare
This pull request was exported from Phabricator. Differential Revision: D53461821 |
This pull request has been merged in d7dce97. |
Summary:
Changelog: [Android][Added] - introduce native api to access RuntimeExecutor
This is the android equivalent of PR#42758.
From PR#42758
This diff introduces the API that would allow for 1). because react context can be non-null before react instance is ready, i created an async api that will guarantee the runtime executor will be ready.
Differential Revision: D53461821