Measure how many bytes are received per plugin

Summary:
Measure how many byte we receive per plugin, and add this to the plugin stats that are collected

Will add a graph to the flipper dashboard, and probably a small visualization in a next diff as well.

Reviewed By: priteshrnandgaonkar

Differential Revision: D20917583

fbshipit-source-id: bb341531ecf8492080af82c56e73c0ec608f7b36
This commit is contained in:
Michel Weststrate
2020-04-08 13:03:41 -07:00
committed by Facebook GitHub Bot
parent 52b244ca32
commit bc6165bbfe
3 changed files with 60 additions and 7 deletions

View File

@@ -27,6 +27,7 @@ import {flipperRecorderAddEvent} from './utils/pluginStateRecorder';
import {getPluginKey} from './utils/pluginUtils'; import {getPluginKey} from './utils/pluginUtils';
import {processMessageLater} from './utils/messageQueue'; import {processMessageLater} from './utils/messageQueue';
import {sideEffect} from './utils/sideEffect'; import {sideEffect} from './utils/sideEffect';
import {emitBytesReceived} from './dispatcher/tracking';
type Plugins = Array<string>; type Plugins = Array<string>;
@@ -321,6 +322,8 @@ export default class Client extends EventEmitter {
} else if (method === 'execute') { } else if (method === 'execute') {
invariant(data.params, 'expected params'); invariant(data.params, 'expected params');
const params: Params = data.params; const params: Params = data.params;
const bytes = msg.length * 2; // string lengths are measured in UTF-16 units (not characters), so 2 bytes per char
emitBytesReceived(params.api, bytes);
const persistingPlugin: const persistingPlugin:
| typeof FlipperPlugin | typeof FlipperPlugin
@@ -459,10 +462,15 @@ export default class Client extends EventEmitter {
if (!fromPlugin || this.isAcceptingMessagesFromPlugin(plugin)) { if (!fromPlugin || this.isAcceptingMessagesFromPlugin(plugin)) {
const logEventName = this.getLogEventName(data); const logEventName = this.getLogEventName(data);
this.logger.trackTimeSince(mark, logEventName); this.logger.trackTimeSince(mark, logEventName);
emitBytesReceived(
plugin || 'unknown',
payload.data.length * 2,
);
const response: { const response: {
success?: Object; success?: Object;
error?: ErrorType; error?: ErrorType;
} = JSON.parse(payload.data); } = JSON.parse(payload.data);
this.onResponse(response, resolve, reject); this.onResponse(response, resolve, reject);
} }
}, },

View File

@@ -42,6 +42,28 @@ export type UsageSummary = {
export const fpsEmitter = new EventEmitter(); export const fpsEmitter = new EventEmitter();
// var is fine, let doesn't have the correct hoisting semantics
// eslint-disable-next-line no-var
var bytesReceivedEmitter: EventEmitter;
export function onBytesReceived(
callback: (plugin: string, bytes: number) => void,
): () => void {
if (!bytesReceivedEmitter) {
bytesReceivedEmitter = new EventEmitter();
}
bytesReceivedEmitter.on('bytesReceived', callback);
return () => {
bytesReceivedEmitter.off('bytesReceived', callback);
};
}
export function emitBytesReceived(plugin: string, bytes: number) {
if (bytesReceivedEmitter) {
bytesReceivedEmitter.emit('bytesReceived', plugin, bytes);
}
}
export default (store: Store, logger: Logger) => { export default (store: Store, logger: Logger) => {
let droppedFrames: number = 0; let droppedFrames: number = 0;
let largeFrameDrops: number = 0; let largeFrameDrops: number = 0;

View File

@@ -19,6 +19,7 @@ import {
import {Idler, BaseIdler} from './Idler'; import {Idler, BaseIdler} from './Idler';
import {pluginIsStarred, getSelectedPluginKey} from '../reducers/connections'; import {pluginIsStarred, getSelectedPluginKey} from '../reducers/connections';
import {deconstructPluginKey} from './clientUtils'; import {deconstructPluginKey} from './clientUtils';
import {onBytesReceived} from '../dispatcher/tracking';
const MAX_BACKGROUND_TASK_TIME = 25; const MAX_BACKGROUND_TASK_TIME = 25;
@@ -28,6 +29,8 @@ type StatEntry = {
messageCountTotal: number; // amount of message received for this plugin messageCountTotal: number; // amount of message received for this plugin
messageCountDelta: number; // amout of messages received since previous tracking tick messageCountDelta: number; // amout of messages received since previous tracking tick
maxTime: number; // maximum time spend in a single reducer call maxTime: number; // maximum time spend in a single reducer call
bytesReceivedTotal: number; // Bytes received
bytesReceivedDelta: number; // Bytes received since last tick
}; };
const pluginBackgroundStats = new Map<string, StatEntry>(); const pluginBackgroundStats = new Map<string, StatEntry>();
@@ -36,9 +39,19 @@ export function resetPluginBackgroundStatsDelta() {
pluginBackgroundStats.forEach((stat) => { pluginBackgroundStats.forEach((stat) => {
stat.cpuTimeDelta = 0; stat.cpuTimeDelta = 0;
stat.messageCountDelta = 0; stat.messageCountDelta = 0;
stat.bytesReceivedDelta = 0;
}); });
} }
onBytesReceived((plugin: string, bytes: number) => {
if (!pluginBackgroundStats.has(plugin)) {
pluginBackgroundStats.set(plugin, createEmptyStat());
}
const stat = pluginBackgroundStats.get(plugin)!;
stat.bytesReceivedTotal += bytes;
stat.bytesReceivedDelta += bytes;
});
export function getPluginBackgroundStats(): { export function getPluginBackgroundStats(): {
cpuTime: number; // amount of ms cpu used since the last stats (typically every minute) cpuTime: number; // amount of ms cpu used since the last stats (typically every minute)
byPlugin: {[plugin: string]: StatEntry}; byPlugin: {[plugin: string]: StatEntry};
@@ -71,6 +84,8 @@ if (window) {
messageCountDelta, messageCountDelta,
messageCountTotal, messageCountTotal,
maxTime, maxTime,
bytesReceivedTotal,
bytesReceivedDelta,
}, },
]) => ({ ]) => ({
plugin, plugin,
@@ -79,21 +94,29 @@ if (window) {
cpuTimeDelta, cpuTimeDelta,
messageCountDelta, messageCountDelta,
maxTime, maxTime,
bytesReceivedTotal,
bytesReceivedDelta,
}), }),
), ),
); );
}; };
} }
function addBackgroundStat(plugin: string, cpuTime: number) { function createEmptyStat(): StatEntry {
if (!pluginBackgroundStats.has(plugin)) { return {
pluginBackgroundStats.set(plugin, {
cpuTimeDelta: 0, cpuTimeDelta: 0,
cpuTimeTotal: 0, cpuTimeTotal: 0,
messageCountDelta: 0, messageCountDelta: 0,
messageCountTotal: 0, messageCountTotal: 0,
maxTime: 0, maxTime: 0,
}); bytesReceivedTotal: 0,
bytesReceivedDelta: 0,
};
}
function addBackgroundStat(plugin: string, cpuTime: number) {
if (!pluginBackgroundStats.has(plugin)) {
pluginBackgroundStats.set(plugin, createEmptyStat());
} }
const stat = pluginBackgroundStats.get(plugin)!; const stat = pluginBackgroundStats.get(plugin)!;
stat.cpuTimeDelta += cpuTime; stat.cpuTimeDelta += cpuTime;