mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
track maximum cdp proxy messages from device queue size (#49945)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49945 Changelog: [General][Internal] track maximum cdp messages from device queue size Reviewed By: robhogan Differential Revision: D70404011 fbshipit-source-id: 0191301b27f25ab91b2e9549dd14fd9e40bd825e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2aeccf2b90
commit
b899a0013b
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
// $FlowFixMe[cannot-resolve-module] libdef missing in RN OSS
|
||||
import type {Timeout} from 'timers';
|
||||
|
||||
// $FlowFixMe[cannot-resolve-module] libdef missing in RN OSS
|
||||
import {setTimeout} from 'timers';
|
||||
|
||||
const MAX_QUEUE_TIME_SPAN_MS = 3000;
|
||||
|
||||
export default class CDPMessagesQueueLogging {
|
||||
#messageQueueSize = 0;
|
||||
#maxMessageQueueSize = 0;
|
||||
|
||||
#messagesMemoryUsage = 0;
|
||||
#maxMessageQueueCombinedStringSize = 0;
|
||||
|
||||
#loggingTimeout: Timeout | null = null;
|
||||
|
||||
#debounceStartMs = 0;
|
||||
|
||||
#onHighMessageQueueSize: (queueSize: number, memoryUsageMiB: number) => void;
|
||||
|
||||
constructor(
|
||||
onHighMessageQueueSize: (queueSize: number, memoryUsageMiB: number) => void,
|
||||
) {
|
||||
this.#onHighMessageQueueSize = onHighMessageQueueSize;
|
||||
}
|
||||
|
||||
messageReceived(messageSize: number) {
|
||||
this.#messageQueueSize++;
|
||||
this.#messagesMemoryUsage += messageSize;
|
||||
|
||||
if (this.#messageQueueSize > this.#maxMessageQueueSize) {
|
||||
this.#maxMessageQueueSize = this.#messageQueueSize;
|
||||
this.#maxMessageQueueCombinedStringSize = this.#messagesMemoryUsage;
|
||||
|
||||
// we only report when there were no higher queue size reached for MAX_QUEUE_TIME_SPAN_MS
|
||||
if (this.#loggingTimeout) {
|
||||
this.#loggingTimeout.refresh();
|
||||
} else {
|
||||
this.#debounceStartMs = new Date().getTime();
|
||||
|
||||
this.#loggingTimeout = setTimeout(() => {
|
||||
this.#onHighMessageQueueSize(
|
||||
this.#maxMessageQueueSize,
|
||||
// JS uses around 2 bytes per character
|
||||
this.#maxMessageQueueCombinedStringSize * 2,
|
||||
);
|
||||
|
||||
this.#loggingTimeout = null;
|
||||
this.#maxMessageQueueSize = 0;
|
||||
this.#maxMessageQueueCombinedStringSize = 0;
|
||||
}, MAX_QUEUE_TIME_SPAN_MS).unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageProcessed(messageSize: number) {
|
||||
this.#messageQueueSize--;
|
||||
this.#messagesMemoryUsage -= messageSize;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import type {
|
||||
} from './types';
|
||||
|
||||
import CDPMessagesLogging from './CDPMessagesLogging';
|
||||
import CDPMessagesQueueLogging from './CDPMessagesQueueLogging';
|
||||
import DeviceEventReporter from './DeviceEventReporter';
|
||||
import * as fs from 'fs';
|
||||
import invariant from 'invariant';
|
||||
@@ -37,6 +38,7 @@ import WS from 'ws';
|
||||
const debug = require('debug')('Metro:InspectorProxy');
|
||||
|
||||
const PAGES_POLLING_INTERVAL = 1000;
|
||||
const MIN_MESSAGE_QUEUE_BYTES_TO_REPORT = 2 * 1024 * 1024; // 2 MiB
|
||||
|
||||
// Prefix for script URLs that are alphanumeric IDs. See comment in #processMessageFromDeviceLegacy method for
|
||||
// more details.
|
||||
@@ -88,6 +90,9 @@ export default class Device {
|
||||
// async fetch.
|
||||
#messageFromDeviceQueue: Promise<void> = Promise.resolve();
|
||||
|
||||
// Logging reporting the maximum size of cdp message coming from device in the queue for processing
|
||||
#messageFromDeviceQueueLogging: ?CDPMessagesQueueLogging;
|
||||
|
||||
// Stores socket connection between Inspector Proxy and device.
|
||||
#deviceSocket: WS;
|
||||
|
||||
@@ -130,6 +135,7 @@ export default class Device {
|
||||
// A base HTTP(S) URL to the server, relative to this server.
|
||||
#serverRelativeBaseUrl: URL;
|
||||
|
||||
// Logging reporting batches of cdp messages
|
||||
#cdpMessagesLogging: CDPMessagesLogging;
|
||||
|
||||
constructor(deviceOptions: DeviceOptions) {
|
||||
@@ -152,6 +158,35 @@ export default class Device {
|
||||
this.#id = id;
|
||||
this.#name = name;
|
||||
this.#app = app;
|
||||
|
||||
this.#messageFromDeviceQueueLogging = new CDPMessagesQueueLogging(
|
||||
(maxCDPMessageQueueSize: number, maxCDPMessageQueueMemory: number) => {
|
||||
if (maxCDPMessageQueueMemory > MIN_MESSAGE_QUEUE_BYTES_TO_REPORT) {
|
||||
debug(
|
||||
"CDP messages proxy queue reached='%d' messages using at least '%sMiB' coming from device='%s' for app='%s'",
|
||||
maxCDPMessageQueueSize,
|
||||
String(maxCDPMessageQueueMemory / 1024 / 1024).slice(0, 6),
|
||||
name,
|
||||
app,
|
||||
);
|
||||
|
||||
const debuggerSessionIDs = {
|
||||
appId: app,
|
||||
deviceId: id,
|
||||
deviceName: name,
|
||||
pageId: null,
|
||||
};
|
||||
|
||||
eventReporter?.logEvent({
|
||||
type: 'device_high_message_queue',
|
||||
maxCDPMessageQueueSize,
|
||||
maxCDPMessageQueueMemory,
|
||||
...debuggerSessionIDs,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.#deviceSocket = socket;
|
||||
this.#projectRoot = projectRoot;
|
||||
this.#serverRelativeBaseUrl = serverRelativeBaseUrl;
|
||||
@@ -171,6 +206,7 @@ export default class Device {
|
||||
|
||||
// $FlowFixMe[incompatible-call]
|
||||
this.#deviceSocket.on('message', (message: string) => {
|
||||
this.#messageFromDeviceQueueLogging?.messageReceived(message.length);
|
||||
this.#messageFromDeviceQueue = this.#messageFromDeviceQueue
|
||||
.then(async () => {
|
||||
const parsedMessage = JSON.parse(message);
|
||||
@@ -199,6 +235,9 @@ export default class Device {
|
||||
loggingError,
|
||||
);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.#messageFromDeviceQueueLogging?.messageProcessed(message.length);
|
||||
});
|
||||
});
|
||||
// Sends 'getPages' request to device every PAGES_POLLING_INTERVAL milliseconds.
|
||||
|
||||
@@ -118,6 +118,12 @@ export type ReportableEvent =
|
||||
maxEventLoopDelayPercent: number,
|
||||
duration: number,
|
||||
...DebuggerSessionIDs,
|
||||
}
|
||||
| {
|
||||
type: 'device_high_message_queue',
|
||||
maxCDPMessageQueueSize: number,
|
||||
maxCDPMessageQueueMemory: number,
|
||||
...DebuggerSessionIDs,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user