Merge pull request #75 from realm/sk-session-id

Fix crash when reloading app during Chrome debugging
This commit is contained in:
Scott Kyle 2015-10-20 16:53:29 -07:00
commit a8c1728502
4 changed files with 40 additions and 22 deletions

View File

@ -119,12 +119,15 @@ Object.defineProperties(Realm, {
value: Object.freeze(propTypes),
},
defaultPath: {
get: rpc.getDefaultPath,
set: rpc.setDefaultPath,
get: util.getterForProperty('defaultPath'),
set: util.setterForProperty('defaultPath'),
},
clearTestState: {
value: rpc.clearTestState,
},
});
// The session ID refers to the Realm constructor object in the RPC server.
Realm[keys.id] = rpc.createSession();
module.exports = Realm;

View File

@ -7,6 +7,7 @@ let DEVICE_HOST = 'localhost:8082';
let {keys, objectTypes, propTypes} = constants;
let typeConverters = {};
let XMLHttpRequest = window.XMLHttpRequest;
let sessionId;
// Check if XMLHttpRequest has been overridden, and get the native one if that's the case.
if (XMLHttpRequest.__proto__ != window.XMLHttpRequestEventTarget) {
@ -19,8 +20,7 @@ if (XMLHttpRequest.__proto__ != window.XMLHttpRequestEventTarget) {
module.exports = {
registerTypeConverter,
getDefaultPath,
setDefaultPath,
createSession,
createRealm,
callMethod,
getProperty,
@ -36,12 +36,9 @@ function registerTypeConverter(type, handler) {
typeConverters[type] = handler;
}
function getDefaultPath() {
return sendRequest('get_default_path');
}
function setDefaultPath(path) {
sendRequest('set_default_path', {path});
function createSession() {
sessionId = sendRequest('create_session');
return sessionId;
}
function createRealm(args) {
@ -137,7 +134,9 @@ function deserialize(realmId, info) {
}
function sendRequest(command, data) {
let body = JSON.stringify(data || {});
data = Object.assign({}, data, sessionId ? {sessionId} : null);
let body = JSON.stringify(data);
let request = new XMLHttpRequest();
let url = 'http://' + DEVICE_HOST + '/' + command;

View File

@ -31,7 +31,5 @@ JSClassRef RJSNotificationClass();
std::string RJSDefaultPath();
void RJSSetDefaultPath(std::string path);
JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);
std::map<std::string, realm::ObjectDefaults> &RJSDefaults(realm::Realm *realm);
std::map<std::string, JSValueRef> &RJSPrototypes(realm::Realm *realm);

View File

@ -44,6 +44,7 @@ static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
JSGlobalContextRef _context;
std::map<std::string, RPCRequest> _requests;
std::map<RPCObjectID, JSObjectRef> _objects;
RPCObjectID _sessionID;
}
- (void)dealloc {
@ -70,15 +71,22 @@ static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
id _self = self;
__weak __typeof__(self) self = _self;
_requests["/get_default_path"] = [=](NSDictionary *dict) {
return @{@"result": @(RJSDefaultPath().c_str())};
};
_requests["/set_default_path"] = [=](NSDictionary *dict) {
NSString *path = dict[@"path"];
RJSSetDefaultPath(path.UTF8String);
return nil;
_requests["/create_session"] = [=](NSDictionary *dict) {
[RealmJS initializeContext:_context];
JSStringRef realmString = RJSStringForString("Realm");
JSObjectRef realmConstructor = RJSValidatedObjectProperty(_context, JSContextGetGlobalObject(_context), realmString);
JSStringRelease(realmString);
_sessionID = [self storeObject:realmConstructor];
return @{@"result": @(_sessionID)};
};
_requests["/create_realm"] = [=](NSDictionary *dict) {
JSObjectRef realmConstructor = _sessionID ? _objects[_sessionID] : NULL;
if (!realmConstructor) {
throw std::runtime_error("Realm constructor not found!");
}
NSArray *args = dict[@"arguments"];
NSUInteger argCount = args.count;
JSValueRef argValues[argCount];
@ -88,7 +96,7 @@ static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
}
JSValueRef exception = NULL;
JSObjectRef realmObject = RealmConstructor(_context, NULL, argCount, argValues, &exception);
JSObjectRef realmObject = JSObjectCallAsConstructor(_context, realmConstructor, argCount, argValues, &exception);
if (exception) {
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
@ -165,9 +173,14 @@ static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
};
_requests["/clear_test_state"] = [=](NSDictionary *dict) {
for (auto object : _objects) {
// The session ID points to the Realm constructor object, which should remain.
if (object.first == _sessionID) {
continue;
}
JSValueUnprotect(_context, object.second);
_objects.erase(object.first);
}
_objects.clear();
JSGarbageCollect(_context);
[RealmJS clearTestState];
return nil;
@ -183,6 +196,11 @@ static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
__block id response;
dispatch_sync(dispatch_get_main_queue(), ^{
if (_sessionID != [args[@"sessionId"] unsignedLongValue]) {
response = @{@"error": @"Invalid session ID"};
return;
}
try {
response = action(args);
} catch (std::exception &exception) {