Process and render messages when a plugin is opened

Summary: This introduces the necessary UI changes, to kick off and render event progressing process where needed

Reviewed By: jknoxville

Differential Revision: D19175450

fbshipit-source-id: 61e3e8f59eeebf97eedbe715fa7db320286543e2
This commit is contained in:
Michel Weststrate
2020-01-02 07:12:06 -08:00
committed by Facebook Github Bot
parent d2a2e2ab75
commit 8c8f360572
6 changed files with 212 additions and 70 deletions

View File

@@ -123,7 +123,7 @@ test('queue - events are NOT processed immediately if plugin is NOT selected', a
// process the message
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
await processMessageQueue(client, TestPlugin, pluginKey, store);
await processMessageQueue(TestPlugin, pluginKey, store);
expect(store.getState().pluginStates).toEqual({
[pluginKey]: {
count: 3,
@@ -163,7 +163,6 @@ test('queue - events processing will be paused', async () => {
const idler = new TestIdler();
const p = processMessageQueue(
client,
TestPlugin,
pluginKey,
store,
@@ -224,7 +223,6 @@ test('queue - messages that arrive during processing will be queued', async () =
const idler = new TestIdler();
const p = processMessageQueue(
client,
TestPlugin,
pluginKey,
store,
@@ -288,7 +286,6 @@ test('queue - processing can be cancelled', async () => {
const idler = new TestIdler();
const p = processMessageQueue(
client,
TestPlugin,
pluginKey,
store,

View File

@@ -63,6 +63,7 @@ const ICONS = {
cross: [16],
checkmark: [16],
dashboard: [12],
'dashboard-outline': [24],
desktop: [12],
directions: [12],
download: [16],

View File

@@ -17,19 +17,27 @@ import {
Message,
} from '../reducers/pluginMessageQueue';
import {Idler, BaseIdler} from './Idler';
import Client from '../Client';
import {getPluginKey} from './pluginUtils';
const MAX_BACKGROUND_TASK_TIME = 25;
const pluginBackgroundStats = new Map<
string,
{
cpuTime: number; // Total time spend in persisted Reducer
messages: number; // amount of message received for this plugin
maxTime: number; // maximum time spend in a single reducer call
}
>();
type StatEntry = {
cpuTime: number; // Total time spend in persisted Reducer
messages: number; // amount of message received for this plugin
maxTime: number; // maximum time spend in a single reducer call
};
const pluginBackgroundStats = new Map<string, StatEntry>();
export function getPluginBackgroundStats(): {[plugin: string]: StatEntry} {
return Array.from(Object.entries(pluginBackgroundStats)).reduce(
(aggregated, [pluginName, data]) => {
aggregated[pluginName] = data;
return aggregated;
},
{} as {[plugin: string]: StatEntry},
);
}
if (window) {
// @ts-ignore
@@ -135,7 +143,7 @@ export function processMessageLater(
// if the plugin is active, and has no queued messaged, process the message immediately
if (
selectedPlugin === pluginKey &&
getMessages(store, pluginKey).length === 0
getPendingMessages(store, pluginKey).length === 0
) {
processMessageImmediately(store, pluginKey, plugin, message);
} else {
@@ -146,25 +154,26 @@ export function processMessageLater(
}
export async function processMessageQueue(
client: Client,
plugin: {
defaultPersistedState: any;
name: string;
persistedStateReducer: PersistedStateReducer;
persistedStateReducer: PersistedStateReducer | null;
},
pluginKey: string,
store: Store,
progressCallback?: (progress: string) => void,
progressCallback?: (progress: {current: number; total: number}) => void,
idler: BaseIdler = new Idler(),
) {
const total = getMessages(store, pluginKey).length;
if (!plugin.persistedStateReducer) {
return;
}
const total = getPendingMessages(store, pluginKey).length;
let progress = 0;
do {
const messages = getMessages(store, pluginKey);
const messages = getPendingMessages(store, pluginKey);
if (!messages.length) {
break;
}
// there are messages to process! lets do so until we have to idle
const persistedState =
store.getState().pluginStates[pluginKey] ??
@@ -181,12 +190,10 @@ export async function processMessageQueue(
offset++;
progress++;
progressCallback?.(
`Processing events ${progress} / ${Math.max(
total,
progress,
)} (${Math.min(100, 100 * (progress / total))}%)`,
);
progressCallback?.({
total: Math.max(total, progress),
current: progress,
});
} while (offset < messages.length && !idler.shouldIdle());
// save progress
// by writing progress away first and then idling, we make sure this logic is
@@ -205,11 +212,12 @@ export async function processMessageQueue(
if (idler.isCancelled()) {
return;
}
await idler.idle();
// new messages might have arrived, so keep looping
} while (getMessages(store, pluginKey).length);
} while (getPendingMessages(store, pluginKey).length);
}
function getMessages(store: Store, pluginKey: string): Message[] {
function getPendingMessages(store: Store, pluginKey: string): Message[] {
return store.getState().pluginMessageQueue[pluginKey] || [];
}