Skip to content

Commit

Permalink
Alternative fix for #3236 that avoids causing #3503 (#3505)
Browse files Browse the repository at this point in the history
* Revert "recreate EventLoopDispatcher in NetworkTransport on hot reload in RN (#3340)"

This reverts commit 4c4e497.

* Alternative fix for #3236 that avoids causing #3503

The problem with the fix in #3340 was that it was causing the
EventLoopDispatcher to be constructed on the sync thread rather than on the JS
thread, which is required. This alternative fix initializes it on the JS
thread, but ensures it is re-initialized when RN apps are reloaded.

Co-authored-by: Kenneth Geisshirt <[email protected]>
  • Loading branch information
RedBeard0531 and kneth authored Jan 15, 2021
1 parent 83185e1 commit d10f75b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

### Fixed
* Fixed a bug where elements in the `User#identities` array would have a `userId` which was actually an `id` of the identity. ([#3481](https://github.com/realm/realm-js/pull/3481), since v10.0.0-beta.13)
* Fixed a crash after getting a 401 error inside sync. ([#3503](https://github.com/realm/realm-js/issues/3206), since v10.0.0)
* Fixed a bug which could lead to a `BadChangeset Error` (`ProtocolErrorCode=212`).

### Compatibility
Expand Down
1 change: 1 addition & 0 deletions src/js_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class AppClass : public ClassDefinition<T, SharedApp> {
template<typename T>
inline typename T::Function AppClass<T>::create_constructor(ContextType ctx) {
FunctionType app_constructor = ObjectWrap<T, AppClass<T>>::create_constructor(ctx);
NetworkTransport::init(ctx);
return app_constructor;
}

Expand Down
38 changes: 20 additions & 18 deletions src/js_network_transport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,7 @@ struct JavaScriptNetworkTransport : public app::GenericNetworkTransport {
using NetworkTransportFactory = std::function<std::unique_ptr<app::GenericNetworkTransport>(ContextType)>;
using SendRequestHandler = void(ContextType m_ctx, const app::Request request, std::function<void(const app::Response)> completion_callback);

JavaScriptNetworkTransport(ContextType ctx) : m_ctx(ctx),
m_dispatcher {JavaScriptNetworkTransport::send_request_to_server_impl}
{
};
JavaScriptNetworkTransport(ContextType ctx) : m_ctx(ctx) {};

static ObjectType makeRequest(ContextType ctx, const app::Request& request) {
ObjectType headers_object = Object::create_empty(ctx);
Expand All @@ -191,26 +188,31 @@ struct JavaScriptNetworkTransport : public app::GenericNetworkTransport {
return request_object;
}

void send_request_to_server(const app::Request request, std::function<void(const app::Response)> completion_callback) override {
m_dispatcher(m_ctx, request, completion_callback);
}
static void init(ContextType ctx) {
// This initializes the EventLoopDispatcher on the main JS thread.
s_dispatcher.reset(new realm::util::EventLoopDispatcher([]
(ContextType m_ctx, const app::Request request, std::function<void(const app::Response)> completion_callback) {
HANDLESCOPE(m_ctx);

private:
ContextType m_ctx;
realm::util::EventLoopDispatcher<SendRequestHandler> m_dispatcher;
ObjectType realm_constructor = Value::validated_to_object(m_ctx, Object::get_global(m_ctx, "Realm"));
ValueType network_transport = Object::get_property(m_ctx, realm_constructor, "_networkTransport");

static void send_request_to_server_impl(ContextType m_ctx, const app::Request request, std::function<void(const app::Response)> completion_callback) {
HANDLESCOPE(m_ctx);
Object::call_method(m_ctx, Value::to_object(m_ctx, network_transport), "fetchWithCallbacks", {
makeRequest(m_ctx, request),
ResponseHandlerClass<T>::create_instance(m_ctx, std::move(completion_callback)),
});
}));

ObjectType realm_constructor = Value::validated_to_object(m_ctx, Object::get_global(m_ctx, "Realm"));
ValueType network_transport = Object::get_property(m_ctx, realm_constructor, "_networkTransport");
}

Object::call_method(m_ctx, Value::to_object(m_ctx, network_transport), "fetchWithCallbacks", {
makeRequest(m_ctx, request),
ResponseHandlerClass<T>::create_instance(m_ctx, std::move(completion_callback)),
});
void send_request_to_server(const app::Request request, std::function<void(const app::Response)> completion_callback) override {
(*s_dispatcher)(m_ctx, request, completion_callback);
}

private:
ContextType m_ctx;
inline static std::unique_ptr<realm::util::EventLoopDispatcher<SendRequestHandler>> s_dispatcher;

std::string static fromHttpMethod(app::HttpMethod method) {
switch (method) {
case app::HttpMethod::get: return "GET";
Expand Down

0 comments on commit d10f75b

Please sign in to comment.