UNPKG

rn-blockmonitor

Version:

block monitor

99 lines (92 loc) 2.91 kB
/** * Copyright (c) 2015-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * @flow */ // const infoLog = require('infoLog'); /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error * found when Flow v0.54 was deployed. To see the error delete this comment and * run Flow. */ // type Handler = { // onIterate?: () => void; // onStall: (params: {lastInterval: number; busyTime: number}) => ?string; // }; /** * A utility for tracking stalls in the JS event loop that prevent timers and * other events from being processed in a timely manner. * * The "stall" time is defined as the amount of time in access of the acceptable * threshold, which is typically around 100-200ms. So if the treshold is set to * 100 and a timer fires 150 ms later than it was scheduled because the event * loop was tied up, that would be considered a 50ms stall. * * By default, logs stall events to the console when installed. Can also be * queried with `getStats`. */ const BMJSEventLoopWatchdog = { getStats(): Record<string, any> { return { stallCount, totalStallTime, longestStall, acceptableBusyTime }; }, reset() { console.log('JSEventLoopWatchdog: reset'); // infoLog('BMJSEventLoopWatchdog: reset'); totalStallTime = 0; stallCount = 0; longestStall = 0; lastInterval = new Date().getTime(); }, stop() { stopFlag = true; }, addHandler(handler) { handlers.push(handler); }, install({ thresholdMS }: {thresholdMS: number}) { acceptableBusyTime = thresholdMS; if (installed) { return; } installed = true; lastInterval = new Date().getTime(); function iteration() { const now = new Date().getTime(); const busyTime = now - lastInterval - thresholdMS / 2; if (busyTime >= thresholdMS) { const stallTime = busyTime - thresholdMS; stallCount++; totalStallTime += stallTime; longestStall = Math.max(longestStall, stallTime); let msg = `JSEventLoopWatchdog: JS thread busy for ${busyTime}ms. ` + `${totalStallTime}ms in ${stallCount} stalls so far. `; handlers.forEach((handler) => { msg += handler.onStall({ lastInterval, busyTime, now }) || ''; }); // infoLog(msg); console.log(`${msg}`); } handlers.forEach((handler) => { handler.onIterate && handler.onIterate(); }); lastInterval = now; if (!stopFlag) { setTimeout(iteration, thresholdMS / 2); } } iteration(); } }; let acceptableBusyTime = 0; let installed = false; let totalStallTime = 0; let stallCount = 0; let longestStall = 0; let lastInterval = 0; let stopFlag = false; const handlers: Array<Handler> = []; module.exports = BMJSEventLoopWatchdog;