Make sure requests are sent in sequential order on iOS.

Summary:
blairv recently brought an issue with heap snapshots to our attention:  When
captured from iOS, the viewer would quite regularly hang forever instead of
capturing the snapshot.

Further investigation showed that it was because the message that Hermes sends
to indicate that it had finished sending chunks of the heap snapshot was
arriving to chrome before the last chunk of the snapshot.  This caused Chrome
to believe the snapshot was malformed.

I confirmed that:

 - Sends from the Hermes Inspector were occurring in the correct order.
 - The WebSocket protocol, being built on top of TCP, also preserves order.
 - The Inspector Proxy in Metro was preserving the order of requests it was
   given, but the responses were already in the wrong order when they reached
   it.

This left the code that Hermes' Inspector calls into to send its messages.  On
iOS, the logic to send the request is run on the global dispatch queue which
can and does schedule jobs concurrently with each other.  Because the messages
containing heap snapshot chunks are much larger than the "Ok" message used to
indicate the end of the snapshot, the earlier chunk message would often lose
the race with the later "Ok" message.

There was already a serial background queue used by the websocket server to
schedule the actual sending of the message.  I re-use it in this diff to
process the message as well.

The architecture of the [same code in Android](https://our.intern.facebook.com/intern/diffusion/FBS/browse/master/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorPackagerConnection.java?commit=64c8954ec7be555509437db6944b9a71a350e87c&lines=283) initially seems to be broken in
the same way, but it is not, because AsyncTask does not run tasks concurrently
any more because Google found it exposed too many concurrency bugs to do so.

pakoito, it seems like you might be somewhat familiar with what's going on
here.  Let me know if what I've done is sensible.

Reviewed By: pakoito

Differential Revision: D17106960

fbshipit-source-id: af85ff1753324340bb55fc63048e8bd424c8a983
This commit is contained in:
Ashok Menon 2019-09-04 05:34:44 -07:00 коммит произвёл Facebook Github Bot
Родитель 15b38958b0
Коммит e6d5f2e80d
1 изменённых файлов: 1 добавлений и 1 удалений

Просмотреть файл

@ -287,7 +287,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)sendToPackager:(NSDictionary *)messageObject
{
__weak RCTInspectorPackagerConnection *weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(_jsQueue, ^{
RCTInspectorPackagerConnection *strongSelf = weakSelf;
if (strongSelf && !strongSelf->_closed) {
NSError *error;