2023-05-04 17:59:02 +00:00
|
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import { ipcRenderer } from 'electron';
|
|
|
|
import * as log from '../logging/log';
|
|
|
|
import createTaskWithTimeout from '../textsecure/TaskWithTimeout';
|
|
|
|
import { explodePromise } from '../util/explodePromise';
|
2024-07-22 18:16:33 +00:00
|
|
|
import { missingCaseError } from '../util/missingCaseError';
|
2023-05-04 17:59:02 +00:00
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
const SQL_READ_KEY = 'sql-channel:read';
|
|
|
|
const SQL_WRITE_KEY = 'sql-channel:write';
|
2024-08-12 19:54:24 +00:00
|
|
|
const SQL_REMOVE_DB_KEY = 'sql-channel:remove-db';
|
2023-05-04 17:59:02 +00:00
|
|
|
let activeJobCount = 0;
|
|
|
|
let resolveShutdown: (() => void) | undefined;
|
|
|
|
let shutdownPromise: Promise<void> | null = null;
|
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
export enum AccessType {
|
|
|
|
Read = 'Read',
|
|
|
|
Write = 'Write',
|
|
|
|
}
|
|
|
|
|
2023-08-15 23:24:19 +00:00
|
|
|
export async function ipcInvoke<T>(
|
2024-07-22 18:16:33 +00:00
|
|
|
access: AccessType,
|
2023-05-04 17:59:02 +00:00
|
|
|
name: string,
|
|
|
|
args: ReadonlyArray<unknown>
|
2023-08-15 23:24:19 +00:00
|
|
|
): Promise<T> {
|
2023-05-04 17:59:02 +00:00
|
|
|
const fnName = String(name);
|
|
|
|
|
|
|
|
if (shutdownPromise && name !== 'close') {
|
|
|
|
throw new Error(
|
2024-07-22 18:16:33 +00:00
|
|
|
`Rejecting SQL channel job (${access}, ${fnName}); ` +
|
|
|
|
'application is shutting down'
|
2023-05-04 17:59:02 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
let channel: string;
|
|
|
|
if (access === AccessType.Read) {
|
|
|
|
channel = SQL_READ_KEY;
|
|
|
|
} else if (access === AccessType.Write) {
|
|
|
|
channel = SQL_WRITE_KEY;
|
|
|
|
} else {
|
|
|
|
throw missingCaseError(access);
|
|
|
|
}
|
|
|
|
|
2023-05-04 17:59:02 +00:00
|
|
|
activeJobCount += 1;
|
|
|
|
return createTaskWithTimeout(async () => {
|
|
|
|
try {
|
2024-07-22 18:16:33 +00:00
|
|
|
return await ipcRenderer.invoke(channel, name, ...args);
|
2023-05-04 17:59:02 +00:00
|
|
|
} finally {
|
|
|
|
activeJobCount -= 1;
|
|
|
|
if (activeJobCount === 0) {
|
|
|
|
resolveShutdown?.();
|
|
|
|
}
|
|
|
|
}
|
2024-07-22 18:16:33 +00:00
|
|
|
}, `SQL channel call (${access}, ${fnName})`)();
|
2023-05-04 17:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function doShutdown(): Promise<void> {
|
|
|
|
log.info(
|
|
|
|
`data.shutdown: shutdown requested. ${activeJobCount} jobs outstanding`
|
|
|
|
);
|
|
|
|
|
|
|
|
if (shutdownPromise) {
|
|
|
|
return shutdownPromise;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No outstanding jobs, return immediately
|
|
|
|
if (activeJobCount === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
({ promise: shutdownPromise, resolve: resolveShutdown } =
|
|
|
|
explodePromise<void>());
|
|
|
|
|
|
|
|
try {
|
|
|
|
await shutdownPromise;
|
|
|
|
} finally {
|
|
|
|
log.info('data.shutdown: process complete');
|
|
|
|
}
|
|
|
|
}
|
2024-08-12 19:54:24 +00:00
|
|
|
|
|
|
|
export async function removeDB(): Promise<void> {
|
|
|
|
return ipcRenderer.invoke(SQL_REMOVE_DB_KEY);
|
|
|
|
}
|