RN: Fix Exponential WebSocket Growth from DevTools

Summary:025281230de2e316f2770a2db71f8bec6fe43a07 changed `WebSocket` to fire both `onerror` and `onclose`.

However, `setupDevtools` assumed that only one of the two handlers would ever be invoked. When the handler is invoked, it re-invokes itself to keep a socket open. But since both handelrs are invoked, a series of closed or failed sockets can cause an exponential increase in sockets opened.

Symptoms of this bug include eventually reaching the maximum number of file descriptors allowed by the operating system, or a non-responsive system. Within React Native applications, symptoms include a failure to load resources from the React Native server or application crashes.

Reviewed By: frantic

Differential Revision: D3022697

fb-gh-sync-id: 8131ecbd6d8ba30281253340d30370ff511a5efd
shipit-source-id: 8131ecbd6d8ba30281253340d30370ff511a5efd
This commit is contained in:
Tim Yung 2016-03-07 19:19:20 -08:00 committed by Facebook Github Bot 3
parent 72b274a9b9
commit d0a26a75fb
1 changed files with 11 additions and 8 deletions

View File

@ -30,18 +30,21 @@ function setupDevtools() {
},
},
};
ws.onclose = () => {
setTimeout(setupDevtools, 200);
closeListeners.forEach(fn => fn());
};
ws.onerror = error => {
setTimeout(setupDevtools, 200);
closeListeners.forEach(fn => fn());
};
ws.onclose = handleClose;
ws.onerror = handleClose;
ws.onopen = function () {
tryToConnect();
};
var hasClosed = false;
function handleClose() {
if (!hasClosed) {
hasClosed = true;
setTimeout(setupDevtools, 200);
closeListeners.forEach(fn => fn());
}
}
function tryToConnect() {
ws.send('attach:agent');
var _interval = setInterval(() => ws.send('attach:agent'), 500);