Flush queue every 5ms during JS execution

Summary: public

Implement the iOS side of the optmisation previously implemented in android
(D2485402)

Depends on D2540746

Reviewed By: javache

Differential Revision: D2541118

fb-gh-sync-id: f3590600a6defa2da75c5b7b2cced6ad8bfea6cb
This commit is contained in:
Tadeu Zagallo
2015-10-19 08:02:50 -07:00
committed by facebook-github-bot-2
parent 607527c0d4
commit 31f9a690f3
3 changed files with 42 additions and 8 deletions

View File

@@ -24,7 +24,7 @@
@property (nonatomic, strong, readonly) RCTBridge *batchedBridge; @property (nonatomic, strong, readonly) RCTBridge *batchedBridge;
- (void)_handleBuffer:(id)buffer; - (void)handleBuffer:(id)buffer;
- (void)setUp; - (void)setUp;
@end @end
@@ -169,7 +169,7 @@ _Pragma("clang diagnostic pop")
NSArray *args = @[@1234, @5678, @"stringy", @{@"a": @1}, @42]; NSArray *args = @[@1234, @5678, @"stringy", @{@"a": @1}, @42];
NSArray *buffer = @[@[testModuleID], @[testMethodID], @[args], @[], @1234567]; NSArray *buffer = @[@[testModuleID], @[testMethodID], @[args], @[], @1234567];
[_bridge.batchedBridge _handleBuffer:buffer]; [_bridge.batchedBridge handleBuffer:buffer];
dispatch_sync(_methodQueue, ^{ dispatch_sync(_methodQueue, ^{
// clear the queue // clear the queue
@@ -180,7 +180,7 @@ _Pragma("clang diagnostic pop")
- (void)DISABLED_testBadArgumentsCount - (void)DISABLED_testBadArgumentsCount
{ {
//NSArray *bufferWithMissingArgument = @[@[@1], @[@0], @[@[@1234, @5678, @"stringy", @{@"a": @1}/*, @42*/]], @[], @1234567]; //NSArray *bufferWithMissingArgument = @[@[@1], @[@0], @[@[@1234, @5678, @"stringy", @{@"a": @1}/*, @42*/]], @[], @1234567];
//[_bridge _handleBuffer:bufferWithMissingArgument]; //[_bridge handleBuffer:bufferWithMissingArgument];
NSLog(@"WARNING: testBadArgumentsCount is temporarily disabled until we have a better way to test cases that we expect to trigger redbox errors"); NSLog(@"WARNING: testBadArgumentsCount is temporarily disabled until we have a better way to test cases that we expect to trigger redbox errors");
} }

View File

@@ -63,6 +63,7 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void);
{ {
BOOL _loading; BOOL _loading;
BOOL _valid; BOOL _valid;
BOOL _wasBatchActive;
__weak id<RCTJavaScriptExecutor> _javaScriptExecutor; __weak id<RCTJavaScriptExecutor> _javaScriptExecutor;
NSMutableArray *_pendingCalls; NSMutableArray *_pendingCalls;
NSMutableArray *_moduleDataByID; NSMutableArray *_moduleDataByID;
@@ -386,6 +387,7 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void);
// timing issues with RCTRootView // timing issues with RCTRootView
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self didFinishLoading]; [self didFinishLoading];
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification [[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification
object:_parentBridge object:_parentBridge
userInfo:@{ @"bridge": self }]; userInfo:@{ @"bridge": self }];
@@ -613,7 +615,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
@"error": RCTNullIfNil(error), @"error": RCTNullIfNil(error),
}); });
[self _handleBuffer:json]; [self handleBuffer:json batchEnded:YES];
onComplete(error); onComplete(error);
}]; }];
@@ -669,7 +671,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
return; return;
} }
[[NSNotificationCenter defaultCenter] postNotificationName:RCTDequeueNotification object:nil userInfo:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:RCTDequeueNotification object:nil userInfo:nil];
[self _handleBuffer:json]; [self handleBuffer:json batchEnded:YES];
}; };
[_javaScriptExecutor executeJSCall:module [_javaScriptExecutor executeJSCall:module
@@ -680,14 +682,26 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
#pragma mark - Payload Processing #pragma mark - Payload Processing
- (void)_handleBuffer:(id)buffer - (void)handleBuffer:(id)buffer batchEnded:(BOOL)batchEnded
{ {
RCTAssertJSThread(); RCTAssertJSThread();
if (buffer == nil || buffer == (id)kCFNull) { if (buffer != nil && buffer != (id)kCFNull) {
return; _wasBatchActive = YES;
[self handleBuffer:buffer];
} }
if (batchEnded) {
if (_wasBatchActive) {
[self batchDidComplete];
}
_wasBatchActive = NO;
}
}
- (void)handleBuffer:(id)buffer
{
NSArray *requestsArray = [RCTConvert NSArray:buffer]; NSArray *requestsArray = [RCTConvert NSArray:buffer];
#if RCT_DEBUG #if RCT_DEBUG
@@ -765,7 +779,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
dispatch_async(queue, block); dispatch_async(queue, block);
} }
} }
}
- (void)batchDidComplete
{
// TODO: batchDidComplete is only used by RCTUIManager - can we eliminate this special case? // TODO: batchDidComplete is only used by RCTUIManager - can we eliminate this special case?
for (RCTModuleData *moduleData in _moduleDataByID) { for (RCTModuleData *moduleData in _moduleDataByID) {
if ([moduleData.instance respondsToSelector:@selector(batchDidComplete)]) { if ([moduleData.instance respondsToSelector:@selector(batchDidComplete)]) {

View File

@@ -90,6 +90,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
@end @end
// Private bridge interface to allow middle-batch calls
@interface RCTBridge (RCTContextExecutor)
- (void)handleBuffer:(NSArray *)buffer batchEnded:(BOOL)hasEnded;
@end
@implementation RCTContextExecutor @implementation RCTContextExecutor
{ {
RCTJavaScriptContext *_context; RCTJavaScriptContext *_context;
@@ -336,6 +343,16 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
} }
[strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"]; [strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"];
[strongSelf _addNativeHook:RCTNoop withName:"noop"]; [strongSelf _addNativeHook:RCTNoop withName:"noop"];
__weak RCTBridge *bridge = strongSelf->_bridge;
strongSelf->_context.context[@"nativeFlushQueueImmediate"] = ^(NSArray *calls){
if (!weakSelf.valid || !calls) {
return;
}
[bridge handleBuffer:calls batchEnded:NO];
};
#if RCT_DEV #if RCT_DEV
[strongSelf _addNativeHook:RCTNativeTraceBeginSection withName:"nativeTraceBeginSection"]; [strongSelf _addNativeHook:RCTNativeTraceBeginSection withName:"nativeTraceBeginSection"];
[strongSelf _addNativeHook:RCTNativeTraceEndSection withName:"nativeTraceEndSection"]; [strongSelf _addNativeHook:RCTNativeTraceEndSection withName:"nativeTraceEndSection"];