Replies: 4 comments 5 replies
-
WindowsGoing to provide the windows version of this documentation for completeness: In winrt::Microsoft::ReactNative::ExecuteJsi(reactContext, [](facebook::jsi::Runtime& runtime) {
// do stuff on JS thread
} If you require a RuntimeExecutor to pass around cross platform code, a simple implementation of one would be: auto runtimeExecutor = [reactContext](std::function<void(facebook::jsi::Runtime& runtime)>&& callback) {
winrt::Microsoft::ReactNative::ExecuteJsi(reactContext, std::move(callback));
}
All of these methods and APIs will remain unchanged when enabling bridgeless mode in the future. |
Beta Was this translation helpful? Give feedback.
-
It is mentioned that we can get the callInvoker on android using: CallInvokerHolder callInvokerHolder = context.getCatalystInstance.getJSCallInvokerHolder(); I think thats missing the brackets on CallInvokerHolder callInvokerHolder = context.getCatalystInstance().getJSCallInvokerHolder(); |
Beta Was this translation helpful? Give feedback.
-
@philIip Awesome work! I presume modules will have to support both Bride and Bridgeless architectures in the mid-term and it seems like Bridgeless provides a thread-safe async way to grab a hold on runtime while Bridge doesn't (as far as I read). How can we ensure runtime will be safely retrieved async for both architectures in the long term? For example, a JS function is passed to JSI and will be used as a callback that will trigger sporadically on the C++ side. Let's say it triggers every minute, and we need a new valid runtime reference to call JS Land back. |
Beta Was this translation helpful? Give feedback.
-
Can anyone please explain me about thread safety of that one? RuntimeExecutor runtimeExecutor = context.getRuntimeExecutor(); my jsi .cpp file:
Now, for example I have some data arriving on tcp socket that was open (so obviously it will be triggered on different thread).
Now this one still crashes the app with 'is thread attached?' error (works correctly if I call the callback from same thread). I understand there's other apps out there that solved it with invoker code, but they took it from catalyst instance, which is just same as old bridge? Is there better/more efficient way to do what I need now in rn 0.74? Because I tested it and unlike it is stated, the jsi::Runtime& runtime doesn't looks thread safe. |
Beta Was this translation helpful? Give feedback.
-
Hi all, with the release of 0.74, we've introduced new APIs and backwards-compatibility for previously unsupported functionality in the bridgeless architecture, such as getting the
CallInvoker
to safely jump to JavaScript thread and retrieving thejsi::Runtime
, which was supported in the bridge architecture. I'd like to summarize those changes in this discussion as well as gather feedback from you all.Immediate access to jsi::Runtime
Bridge
In the bridge architecture, currently we have the following options for immediate access to the runtime. These are not thread safe, and it is up to the consumer to use the runtime correctly by casting it to the correct type, managing its lifecycle, and handling it on the JS thread.
Android
Accessed through
getJavaScriptContextHolder
onReactContext
.iOS
Accessed through exposing the private
runtime
selector via a category onRCTBridge
:Bridgeless
In bridgeless, the above APIs have been made backwards compatible. However, we acknowledge that the ways to handle this raw runtime pointer is a bit hacky and dangerous, so we are currently recommending C++ TurboModules as the solution here. We've added support for C++ TurboModule autolinking in 0.74 so that users of your libraries do not need to change their code in order for your C++ TurboModule to be registered. However, there are some changes that you will need to do in order for this happen.
RN CLI (Android only)
On Android, @cortinico added support for C++ TurboModule autolinking in react-native-community/cli#2296 via the RN CLI, with detailed instructions on how to enable this.
RCT_EXPORT_CXX_MODULE_EXPERIMENTAL (Android and iOS)
Within the RN framework, we've added a macro that will register your C++ TurboModule before startup. This is a temporary solution to encourage authors to explore C++ TurboModules, but incurs a startup cost. We will look to replace this with a solution in the future, but wanted to provide this option to start with. Instructions on how to use are detailed in facebook/react-native#43054.
Asynchronous JavaScript thread access
Bridge
In the bridge architecture, currently we have the following options to safely asynchronously access the JavaScript thread, but not the runtime.
Android
Accessed through the
CatalystInstance
, which is first retrieved from theReactContext
:iOS
Accessed through exposing the private
jsCallInvoker
selector via a category onRCTBridge
:Bridgeless
In the 0.74 bridgeless architecture, we have provided the RuntimeExecutor API. It is similar to CallInvoker but also provides thread safe access to the runtime, making it a good option to install bindings if there is an acceptable async delay. Note that you can also use C++ TurboModules, as their methods will have access to the callInvoker as well.
Android
The RuntimeExecutor is retrieved via a method from the ReactContext. This is forward compatible with bridge.
Then, you can pass it down to C++ layers via JNI to execute code on the JS thread.
iOS
We have provided a protocol that your native module can conform to which will decorate the module with a property that allows them to access the RuntimeExecutor. You need to make your module conform to this protocol and synthesize a selector for the RuntimeExecutor. This is currently not forward compatible in bridge mode, but I am open to that if it seems to cause a lot of forked code.
I hope this post will help answer some of the questions you all have on how to interact with JavaScript land in bridgeless mode. Please let me know if there are any challenges with the migration path here or if the recommendations are not sufficient for your use case. I'm very open to evolving these as I learn about everyones' use cases. Thank you!
Beta Was this translation helpful? Give feedback.
All reactions