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][Multibundling] Split loadApplicationScript to initializeRuntime and loadBundle #22

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@ - (void)executeApplicationScript:(NSData *)script
self->_reactInstance->loadScriptFromString(std::make_unique<NSDataBigString>(script),
sourceUrlStr.UTF8String, !async);
} else {
std::string methodName = async ? "loadApplicationScript" : "loadApplicationScriptSync";
std::string methodName = async ? "loadBundle" : "loadBundleSync";
throw std::logic_error("Attempt to call " + methodName + ": on uninitialized bridge");
}
}];
Expand Down
6 changes: 5 additions & 1 deletion React/CxxBridge/RCTObjcExecutor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@
std::make_unique<JSBigStdString>(folly::toJson(config)));
}

void loadApplicationScript(
void initializeRuntime() {
// We do nothing here since initialization is done in the constructor
}

void loadBundle(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) override {
RCTProfileBeginFlowEvent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public ProxyExecutorException(Throwable cause) {
* @param sourceURL url or file location from which script content was loaded
*/
@DoNotStrip
void loadApplicationScript(String sourceURL) throws ProxyExecutorException;
void loadBundle(String sourceURL) throws ProxyExecutorException;

/**
* Execute javascript method within js context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public enum ReactMarkerConstants {
UNPACKING_JS_BUNDLE_LOADER_CHECK_END,
UNPACKING_JS_BUNDLE_LOADER_EXTRACTED,
UNPACKING_JS_BUNDLE_LOADER_BLOCKED,
loadApplicationScript_startStringConvert,
loadApplicationScript_endStringConvert,
loadBundle_startStringConvert,
loadBundle_endStringConvert,
PRE_SETUP_REACT_CONTEXT_START,
PRE_SETUP_REACT_CONTEXT_END,
PRE_RUN_JS_BUNDLE_START,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void prepareJSRuntime(JSDebuggerCallback callback) {
}
}

public void loadApplicationScript(
public void loadBundle(
String sourceURL, HashMap<String, String> injectedObjects, JSDebuggerCallback callback) {
int requestID = mRequestID.getAndIncrement();
mCallbacks.put(requestID, callback);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ public void close() {
}

@Override
public void loadApplicationScript(String sourceURL) throws JavaJSExecutor.ProxyExecutorException {
public void loadBundle(String sourceURL) throws JavaJSExecutor.ProxyExecutorException {
JSExecutorCallbackFuture callback = new JSExecutorCallbackFuture();
Assertions.assertNotNull(mWebSocketClient)
.loadApplicationScript(sourceURL, mInjectedObjects, callback);
.loadBundle(sourceURL, mInjectedObjects, callback);
try {
callback.get();
} catch (Throwable cause) {
Expand All @@ -177,7 +177,7 @@ public void loadApplicationScript(String sourceURL) throws JavaJSExecutor.ProxyE

@Override
public void setGlobalVariable(String propertyName, String jsonEncodedValue) {
// Store and use in the next loadApplicationScript() call.
// Store and use in the next loadBundle() call.
mInjectedObjects.put(propertyName, jsonEncodedValue);
}
}
4 changes: 2 additions & 2 deletions ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, cons
JReactMarker::logMarker("CREATE_REACT_CONTEXT_END");
break;
case ReactMarker::JS_BUNDLE_STRING_CONVERT_START:
JReactMarker::logMarker("loadApplicationScript_startStringConvert");
JReactMarker::logMarker("loadBundle_startStringConvert");
break;
case ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP:
JReactMarker::logMarker("loadApplicationScript_endStringConvert");
JReactMarker::logMarker("loadBundle_endStringConvert");
break;
case ReactMarker::NATIVE_MODULE_SETUP_START:
JReactMarker::logMarker("NATIVE_MODULE_SETUP_START", tag);
Expand Down
16 changes: 9 additions & 7 deletions ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ ProxyExecutor::~ProxyExecutor() {
m_executor.reset();
}

void ProxyExecutor::loadApplicationScript(
std::unique_ptr<const JSBigString>,
std::string sourceURL) {

void ProxyExecutor::initializeRuntime() {
folly::dynamic nativeModuleConfig = folly::dynamic::array;

{
Expand All @@ -74,13 +71,18 @@ void ProxyExecutor::loadApplicationScript(
"__fbBatchedBridgeConfig",
folly::make_unique<JSBigStdString>(folly::toJson(config)));
}
}

void ProxyExecutor::loadBundle(
std::unique_ptr<const JSBigString>,
std::string sourceURL) {

static auto loadApplicationScript =
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring)>("loadApplicationScript");
static auto loadBundle =
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring)>("loadBundle");

// The proxy ignores the script data passed in.

loadApplicationScript(
loadBundle(
m_executor.get(),
jni::make_jstring(sourceURL).get());
// We can get pending calls here to native but the queue will be drained when
Expand Down
3 changes: 2 additions & 1 deletion ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class ProxyExecutor : public JSExecutor {
ProxyExecutor(jni::global_ref<jobject>&& executorInstance,
std::shared_ptr<ExecutorDelegate> delegate);
virtual ~ProxyExecutor() override;
virtual void loadApplicationScript(
virtual void initializeRuntime() override;
virtual void loadBundle(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) override;
virtual void setBundleRegistry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void test_prepareJSRuntime_ShouldSendCorrectMessage() throws Exception {
}

@Test
public void test_loadApplicationScript_ShouldSendCorrectMessage() throws Exception {
public void test_loadBundle_ShouldSendCorrectMessage() throws Exception {
final JSDebuggerWebSocketClient.JSDebuggerCallback cb =
PowerMockito.mock(JSDebuggerWebSocketClient.JSDebuggerCallback.class);

Expand All @@ -48,7 +48,7 @@ public void test_loadApplicationScript_ShouldSendCorrectMessage() throws Excepti
injectedObjects.put("key1", "value1");
injectedObjects.put("key2", "value2");

client.loadApplicationScript("http://localhost:8080/index.js", injectedObjects, cb);
client.loadBundle("http://localhost:8080/index.js", injectedObjects, cb);
PowerMockito.verifyPrivate(client)
.invoke(
"sendMessage",
Expand Down
25 changes: 13 additions & 12 deletions ReactCommon/cxxreact/Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ void Instance::initializeBridge(
jsQueue->runOnQueueSync([this, &jsef, jsQueue]() mutable {
nativeToJsBridge_ = folly::make_unique<NativeToJsBridge>(
jsef.get(), moduleRegistry_, jsQueue, callback_);

// TODO investigate why it has to be async
nativeToJsBridge_->initializeRuntime();
std::lock_guard<std::mutex> lock(m_syncMutex);
m_syncReady = true;
m_syncCV.notify_all();
Expand All @@ -55,33 +56,33 @@ void Instance::initializeBridge(
CHECK(nativeToJsBridge_);
}

void Instance::loadApplication(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
void Instance::loadBundle(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
callback_->incrementPendingJSCalls();
SystraceSection s("Instance::loadApplication", "sourceURL",
SystraceSection s("Instance::loadBundle", "sourceURL",
sourceURL);
nativeToJsBridge_->loadApplication(std::move(bundleRegistry), std::move(string),
nativeToJsBridge_->loadBundle(std::move(bundleRegistry), std::move(string),
std::move(sourceURL));
}

void Instance::loadApplicationSync(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
void Instance::loadBundleSync(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
std::unique_lock<std::mutex> lock(m_syncMutex);
m_syncCV.wait(lock, [this] { return m_syncReady; });

SystraceSection s("Instance::loadApplicationSync", "sourceURL",
SystraceSection s("Instance::loadBundleSync", "sourceURL",
sourceURL);
nativeToJsBridge_->loadApplicationSync(std::move(bundleRegistry), std::move(string),
nativeToJsBridge_->loadBundleSync(std::move(bundleRegistry), std::move(string),
std::move(sourceURL));
}

void Instance::setSourceURL(std::string sourceURL) {
callback_->incrementPendingJSCalls();
SystraceSection s("Instance::setSourceURL", "sourceURL", sourceURL);

nativeToJsBridge_->loadApplication(nullptr, nullptr, std::move(sourceURL));
nativeToJsBridge_->loadBundle(nullptr, nullptr, std::move(sourceURL));
}

void Instance::loadScriptFromString(std::unique_ptr<const JSBigString> string,
Expand All @@ -90,9 +91,9 @@ void Instance::loadScriptFromString(std::unique_ptr<const JSBigString> string,
SystraceSection s("Instance::loadScriptFromString", "sourceURL",
sourceURL);
if (loadSynchronously) {
loadApplicationSync(nullptr, std::move(string), std::move(sourceURL));
loadBundleSync(nullptr, std::move(string), std::move(sourceURL));
} else {
loadApplication(nullptr, std::move(string), std::move(sourceURL));
loadBundle(nullptr, std::move(string), std::move(sourceURL));
}
}

Expand Down Expand Up @@ -144,10 +145,10 @@ void Instance::loadRAMBundle(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::string startupScriptSourceURL,
bool loadSynchronously) {
if (loadSynchronously) {
loadApplicationSync(std::move(bundleRegistry), std::move(startupScript),
loadBundleSync(std::move(bundleRegistry), std::move(startupScript),
std::move(startupScriptSourceURL));
} else {
loadApplication(std::move(bundleRegistry), std::move(startupScript),
loadBundle(std::move(bundleRegistry), std::move(startupScript),
std::move(startupScriptSourceURL));
}
}
Expand Down
6 changes: 4 additions & 2 deletions ReactCommon/cxxreact/Instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class RN_EXPORT Instance {
std::shared_ptr<MessageQueueThread> jsQueue,
std::shared_ptr<ModuleRegistry> moduleRegistry);

void initializeRuntime();

void setSourceURL(std::string sourceURL);

void loadScriptFromString(std::unique_ptr<const JSBigString> string,
Expand Down Expand Up @@ -77,10 +79,10 @@ class RN_EXPORT Instance {

private:
void callNativeModules(folly::dynamic &&calls, bool isEndOfBatch);
void loadApplication(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
void loadBundle(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL);
void loadApplicationSync(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
void loadBundleSync(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL);

Expand Down
7 changes: 6 additions & 1 deletion ReactCommon/cxxreact/JSExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,15 @@ class JSExecutorFactory {

class RN_EXPORT JSExecutor {
public:
/**
* Sets all globals in the JS context.
*/
virtual void initializeRuntime() = 0;

/**
* Execute an application script bundle in the JS context.
*/
virtual void loadApplicationScript(std::unique_ptr<const JSBigString> script,
virtual void loadBundle(std::unique_ptr<const JSBigString> script,
std::string sourceURL) = 0;

/**
Expand Down
15 changes: 11 additions & 4 deletions ReactCommon/cxxreact/NativeToJsBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ NativeToJsBridge::~NativeToJsBridge() {
"NativeToJsBridge::destroy() must be called before deallocating the NativeToJsBridge!";
}

void NativeToJsBridge::loadApplication(
void NativeToJsBridge::initializeRuntime() {
runOnExecutorQueue([]
(JSExecutor* executor) mutable {
executor->initializeRuntime();
});
}

void NativeToJsBridge::loadBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL) {
Expand All @@ -116,7 +123,7 @@ void NativeToJsBridge::loadApplication(
executor->setBundleRegistry(std::move(bundleRegistry));
}
try {
executor->loadApplicationScript(std::move(*startupScript),
executor->loadBundle(std::move(*startupScript),
std::move(startupScriptSourceURL));
} catch (...) {
m_applicationScriptHasFailure = true;
Expand All @@ -125,15 +132,15 @@ void NativeToJsBridge::loadApplication(
});
}

void NativeToJsBridge::loadApplicationSync(
void NativeToJsBridge::loadBundleSync(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL) {
if (bundleRegistry) {
m_executor->setBundleRegistry(std::move(bundleRegistry));
}
try {
m_executor->loadApplicationScript(std::move(startupScript),
m_executor->loadBundle(std::move(startupScript),
std::move(startupScriptSourceURL));
} catch (...) {
m_applicationScriptHasFailure = true;
Expand Down
11 changes: 8 additions & 3 deletions ReactCommon/cxxreact/NativeToJsBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class RAMBundleRegistry;
// executors and their threads. All functions here can be called from
// any thread.
//
// Except for loadApplicationScriptSync(), all void methods will queue
// Except for loadBundleSync(), all void methods will queue
// work to run on the jsQueue passed to the ctor, and return
// immediately.
class NativeToJsBridge {
Expand All @@ -56,17 +56,22 @@ class NativeToJsBridge {
* Invokes a callback with the cbID, and optional additional arguments in JS.
*/
void invokeCallback(double callbackId, folly::dynamic&& args);

/**
* Sets global variables in the JS Context.
*/
void initializeRuntime();

/**
* Starts the JS application. If bundleRegistry is non-null, then it is
* used to fetch JavaScript modules as individual scripts.
* Otherwise, the script is assumed to include all the modules.
*/
void loadApplication(
void loadBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupCode,
std::string sourceURL);
void loadApplicationSync(
void loadBundleSync(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupCode,
std::string sourceURL);
Expand Down
22 changes: 14 additions & 8 deletions ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,8 @@ JSIExecutor::JSIExecutor(
*runtime, "__jsiExecutorDescription", runtime->description());
}

void JSIExecutor::loadApplicationScript(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) {
SystraceSection s("JSIExecutor::loadApplicationScript");

// TODO: check for and use precompiled HBC

void JSIExecutor::initializeRuntime() {
SystraceSection s("JSIExecutor::initializeRuntime");
runtime_->global().setProperty(
*runtime_,
"nativeModuleProxy",
Expand Down Expand Up @@ -131,6 +126,18 @@ void JSIExecutor::loadApplicationScript(
if (runtimeInstaller_) {
runtimeInstaller_(*runtime_);
}
bool hasLogger(ReactMarker::logTaggedMarker);
if (hasLogger) {
ReactMarker::logMarker(ReactMarker::CREATE_REACT_CONTEXT_STOP);
}
}

void JSIExecutor::loadBundle(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) {
SystraceSection s("JSIExecutor::loadBundle");

// TODO: check for and use precompiled HBC

bool hasLogger(ReactMarker::logTaggedMarker);
std::string scriptName = simpleBasename(sourceURL);
Expand All @@ -142,7 +149,6 @@ void JSIExecutor::loadApplicationScript(
std::make_unique<BigStringBuffer>(std::move(script)), sourceURL);
flush();
if (hasLogger) {
ReactMarker::logMarker(ReactMarker::CREATE_REACT_CONTEXT_STOP);
ReactMarker::logTaggedMarker(
ReactMarker::RUN_JS_BUNDLE_STOP, scriptName.c_str());
}
Expand Down
3 changes: 2 additions & 1 deletion ReactCommon/jsiexecutor/jsireact/JSIExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ class JSIExecutor : public JSExecutor {
std::shared_ptr<ExecutorDelegate> delegate,
const JSIScopedTimeoutInvoker &timeoutInvoker,
RuntimeInstaller runtimeInstaller);
void loadApplicationScript(
void initializeRuntime() override;
void loadBundle(
std::unique_ptr<const JSBigString> script,
std::string sourceURL) override;
void setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) override;
Expand Down