mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-06-10 03:13:32 -07:00
fix(update): separate in-flight dedup keys for manual check vs install
- manual:check and manual:install now tracked independently; install no longer reuses a check's in-flight promise - add toggleNotificationHistory (Ctrl+N) shortcut to config example and docs
This commit is contained in:
@@ -293,6 +293,28 @@ test('concurrent update checks share one in-flight check', async () => {
|
||||
assert.equal(checkCount, 1);
|
||||
});
|
||||
|
||||
test('manual install request does not reuse in-flight manual check', async () => {
|
||||
let checkCount = 0;
|
||||
const resolveChecks: Array<(value: { available: boolean; version: string }) => void> = [];
|
||||
const { deps } = createDeps({
|
||||
checkAppUpdate: () =>
|
||||
new Promise((resolve) => {
|
||||
checkCount += 1;
|
||||
resolveChecks.push(resolve);
|
||||
}),
|
||||
});
|
||||
const service = createUpdateService(deps);
|
||||
const manualCheck = service.checkForUpdates({ source: 'manual' });
|
||||
const manualInstall = service.checkForUpdates({ source: 'manual', installWhenAvailable: true });
|
||||
|
||||
await Promise.resolve();
|
||||
assert.equal(checkCount, 2);
|
||||
for (const resolve of resolveChecks) {
|
||||
resolve({ available: false, version: '0.14.0' });
|
||||
}
|
||||
await Promise.all([manualCheck, manualInstall]);
|
||||
});
|
||||
|
||||
test('manual update check does not reuse in-flight automatic check', async () => {
|
||||
let checkCount = 0;
|
||||
const resolveChecks: Array<(value: { available: boolean; version: string }) => void> = [];
|
||||
|
||||
@@ -108,7 +108,14 @@ function summarizeError(error: unknown): string {
|
||||
}
|
||||
|
||||
export function createUpdateService(deps: UpdateServiceDeps) {
|
||||
const inFlightBySource = new Map<UpdateCheckSource, Promise<UpdateCheckResult>>();
|
||||
const inFlightBySource = new Map<string, Promise<UpdateCheckResult>>();
|
||||
|
||||
function getInFlightKey(request: UpdateCheckRequest): string {
|
||||
if (request.source === 'manual') {
|
||||
return request.installWhenAvailable ? 'manual:install' : 'manual:check';
|
||||
}
|
||||
return request.source;
|
||||
}
|
||||
|
||||
async function runCheck(request: UpdateCheckRequest): Promise<UpdateCheckResult> {
|
||||
const now = deps.now();
|
||||
@@ -206,12 +213,13 @@ export function createUpdateService(deps: UpdateServiceDeps) {
|
||||
|
||||
return {
|
||||
checkForUpdates(request: UpdateCheckRequest): Promise<UpdateCheckResult> {
|
||||
const inFlight = inFlightBySource.get(request.source);
|
||||
const key = getInFlightKey(request);
|
||||
const inFlight = inFlightBySource.get(key);
|
||||
if (inFlight) return inFlight;
|
||||
const nextInFlight = runCheck(request).finally(() => {
|
||||
inFlightBySource.delete(request.source);
|
||||
inFlightBySource.delete(key);
|
||||
});
|
||||
inFlightBySource.set(request.source, nextInFlight);
|
||||
inFlightBySource.set(key, nextInFlight);
|
||||
return nextInFlight;
|
||||
},
|
||||
startAutomaticChecks(options: { startupDelayMs?: number; pollIntervalMs?: number } = {}): void {
|
||||
|
||||
Reference in New Issue
Block a user