Debounce receiving messages
Summary: See previous diff. Achieves the same optimization as in the mentioned diff, but this time by only debouncing the messages as they arrive over the socket, and not the state updates caused by Redux directly. This means that plugin rendering won't be debounced anymore until we address this more fundamentally. With this change there is a double level buffering: 1. A buffer that stores all incoming messages (that are not replies to requests) 2. A buffer that stores messages we are interested in in the plugin queue, unless the plugin is active (this we already had). This still fixes the issue that too chatty plugins cause to many updates foreground plugin (the problem we tried to fix originally), without debouncing plugin rendering if it is needed to update for any other reason. Another nice benefit is that previously every received message would trigger a store update in Redux which would cause all connected components to evaluate their subscriptions (and then bail out in the typical case). Now we will only update the redux store every 200 ms. Changelog: Foreground plugins will burn less CPU when they're very chatty Reviewed By: jknoxville Differential Revision: D21858849 fbshipit-source-id: c72352e569a8a803bbedffb71b17b11fcefee043
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d70b620fae
commit
e31ddbc648
@@ -13,7 +13,7 @@ import {setPluginState} from '../reducers/pluginStates';
|
||||
import {flipperRecorderAddEvent} from './pluginStateRecorder';
|
||||
import {
|
||||
clearMessageQueue,
|
||||
queueMessage,
|
||||
queueMessages,
|
||||
Message,
|
||||
} from '../reducers/pluginMessageQueue';
|
||||
import {Idler, BaseIdler} from './Idler';
|
||||
@@ -143,7 +143,7 @@ function processMessage(
|
||||
id: string;
|
||||
persistedStateReducer: PersistedStateReducer | null;
|
||||
},
|
||||
message: {method: string; params?: any},
|
||||
message: Message,
|
||||
): State {
|
||||
const reducerStartTime = Date.now();
|
||||
flipperRecorderAddEvent(pluginKey, message.method, message.params);
|
||||
@@ -161,7 +161,7 @@ function processMessage(
|
||||
}
|
||||
}
|
||||
|
||||
export function processMessageImmediately(
|
||||
export function processMessagesImmediately(
|
||||
store: MiddlewareAPI,
|
||||
pluginKey: string,
|
||||
plugin: {
|
||||
@@ -169,15 +169,13 @@ export function processMessageImmediately(
|
||||
id: string;
|
||||
persistedStateReducer: PersistedStateReducer | null;
|
||||
},
|
||||
message: {method: string; params?: any},
|
||||
messages: Message[],
|
||||
) {
|
||||
const persistedState = getCurrentPluginState(store, plugin, pluginKey);
|
||||
const newPluginState = processMessage(
|
||||
persistedState,
|
||||
pluginKey,
|
||||
plugin,
|
||||
message,
|
||||
);
|
||||
let newPluginState: any;
|
||||
messages.forEach((message) => {
|
||||
newPluginState = processMessage(persistedState, pluginKey, plugin, message);
|
||||
});
|
||||
if (persistedState !== newPluginState) {
|
||||
store.dispatch(
|
||||
setPluginState({
|
||||
@@ -188,7 +186,7 @@ export function processMessageImmediately(
|
||||
}
|
||||
}
|
||||
|
||||
export function processMessageLater(
|
||||
export function processMessagesLater(
|
||||
store: MiddlewareAPI,
|
||||
pluginKey: string,
|
||||
plugin: {
|
||||
@@ -197,30 +195,24 @@ export function processMessageLater(
|
||||
persistedStateReducer: PersistedStateReducer | null;
|
||||
maxQueueSize?: number;
|
||||
},
|
||||
message: {method: string; params?: any},
|
||||
messages: Message[],
|
||||
) {
|
||||
const isSelected =
|
||||
pluginKey === getSelectedPluginKey(store.getState().connections);
|
||||
switch (true) {
|
||||
case plugin.id === 'Navigation': // Navigation events are always processed, to make sure the navbar stays up to date
|
||||
case isSelected && getPendingMessages(store, pluginKey).length === 0:
|
||||
processMessageImmediately(store, pluginKey, plugin, message);
|
||||
processMessagesImmediately(store, pluginKey, plugin, messages);
|
||||
break;
|
||||
case isSelected:
|
||||
case plugin instanceof FlipperDevicePlugin:
|
||||
case (plugin as any).prototype instanceof FlipperDevicePlugin:
|
||||
case pluginIsStarred(
|
||||
store.getState().connections.userStarredPlugins,
|
||||
deconstructPluginKey(pluginKey).client,
|
||||
plugin.id,
|
||||
):
|
||||
store.dispatch(
|
||||
queueMessage(
|
||||
pluginKey,
|
||||
message.method,
|
||||
message.params,
|
||||
plugin.maxQueueSize,
|
||||
),
|
||||
);
|
||||
store.dispatch(queueMessages(pluginKey, messages, plugin.maxQueueSize));
|
||||
break;
|
||||
default:
|
||||
// In all other cases, messages will be dropped...
|
||||
|
||||
Reference in New Issue
Block a user