Conversation: savePromises for off-queue post-handleDataMessage work

This commit is contained in:
Scott Nonnenberg 2024-08-28 16:05:08 +10:00 committed by GitHub
parent 059c971ee2
commit 768ab26a20
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 145 additions and 62 deletions

View file

@ -8,6 +8,8 @@ import * as log from '../logging/log';
import * as Errors from '../types/errors';
import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary';
import { MINUTE } from './durations';
import { drop } from './drop';
import { explodePromise } from './explodePromise';
declare global {
// We want to extend `window`'s properties, so we need an interface.
@ -52,12 +54,6 @@ type ItemHolderType<ItemType> = {
item: ItemType;
};
type ExplodedPromiseType = {
resolve?: (value?: unknown) => void;
reject?: (error: Error) => void;
promise: Promise<unknown>;
};
type BatcherOptionsType<ItemType> = {
name: string;
wait: number;
@ -70,7 +66,8 @@ type BatcherType<ItemType> = {
anyPending: () => boolean;
onIdle: () => Promise<void>;
unregister: () => void;
flushAndWait: () => void;
flushAndWait: () => Promise<void>;
pushNoopAndWait: () => Promise<void>;
};
export function createWaitBatcher<ItemType>(
@ -86,6 +83,10 @@ export function createWaitBatcher<ItemType>(
});
async function _kickBatchOff() {
if (items.length === 0) {
return;
}
const itemsRef = items;
items = [];
await queue.add(async () => {
@ -106,20 +107,8 @@ export function createWaitBatcher<ItemType>(
});
}
function _makeExplodedPromise(): ExplodedPromiseType {
let resolve;
let reject;
const promise = new Promise((resolveParam, rejectParam) => {
resolve = resolveParam;
reject = rejectParam;
});
return { promise, resolve, reject };
}
async function add(item: ItemType) {
const { promise, resolve, reject } = _makeExplodedPromise();
const { promise, resolve, reject } = explodePromise();
items.push({
resolve,
@ -132,14 +121,14 @@ export function createWaitBatcher<ItemType>(
// time is bounded by `options.wait` and not extended by further pushes.
timeout = setTimeout(() => {
timeout = null;
void _kickBatchOff();
drop(_kickBatchOff());
}, options.wait);
}
if (items.length >= options.maxSize) {
clearTimeoutIfNecessary(timeout);
timeout = null;
void _kickBatchOff();
drop(_kickBatchOff());
}
await promise;
@ -169,6 +158,7 @@ export function createWaitBatcher<ItemType>(
);
}
// Meant for a full shutdown of the queue
async function flushAndWait() {
log.info(
`Flushing start ${options.name} for waitBatcher ` +
@ -190,12 +180,30 @@ export function createWaitBatcher<ItemType>(
log.info(`Flushing complete ${options.name} for waitBatcher`);
}
// Meant to let us know that we've processed jobs up to a point
async function pushNoopAndWait() {
log.info(
`Pushing no-op to ${options.name} for waitBatcher ` +
`items.length=${items.length}`
);
clearTimeoutIfNecessary(timeout);
timeout = null;
drop(_kickBatchOff());
return queue.add(() => {
/* noop */
});
}
waitBatcher = {
add,
anyPending,
onIdle,
unregister,
flushAndWait,
pushNoopAndWait,
};
window.waitBatchers.push(waitBatcher);