From 45685272326dab040ab67be03124af0a9ec5dd2e Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Mon, 27 Jun 2022 09:46:43 -0700 Subject: [PATCH] Increase backstop queue timeouts across the app --- sticker-creator/components/StickerGrid.tsx | 3 ++- ts/ConversationController.ts | 4 ++-- ts/SignalProtocolStore.ts | 5 +++-- ts/background.ts | 4 ++-- ts/components/emoji/lib.ts | 3 ++- ts/indexeddb.ts | 24 +++++++++++++++++----- ts/models/conversations.ts | 2 +- ts/routineProfileRefresh.ts | 3 ++- ts/sql/Client.ts | 3 ++- ts/textsecure/TaskWithTimeout.ts | 2 +- ts/textsecure/WebAPI.ts | 2 +- ts/types/Stickers.ts | 3 ++- ts/util/batcher.ts | 3 ++- ts/util/callingTones.ts | 3 ++- ts/util/sendToGroup.ts | 3 ++- ts/util/waitBatcher.ts | 3 ++- 16 files changed, 47 insertions(+), 23 deletions(-) diff --git a/sticker-creator/components/StickerGrid.tsx b/sticker-creator/components/StickerGrid.tsx index 63c819a4bed..78693b818dc 100644 --- a/sticker-creator/components/StickerGrid.tsx +++ b/sticker-creator/components/StickerGrid.tsx @@ -13,8 +13,9 @@ import type { Props as DropZoneProps } from '../elements/DropZone'; import { DropZone } from '../elements/DropZone'; import { processStickerImage } from '../util/preload'; import { useI18n } from '../util/i18n'; +import { MINUTE } from '../../ts/util/durations'; -const queue = new PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 }); +const queue = new PQueue({ concurrency: 3, timeout: MINUTE * 30 }); type SmartStickerFrameProps = Omit & { id: string }; diff --git a/ts/ConversationController.ts b/ts/ConversationController.ts index df3971de60d..56bc0a7768a 100644 --- a/ts/ConversationController.ts +++ b/ts/ConversationController.ts @@ -22,7 +22,7 @@ import { QualifiedAddress } from './types/QualifiedAddress'; import * as log from './logging/log'; import { sleep } from './util/sleep'; import { isNotNil } from './util/isNotNil'; -import { SECOND } from './util/durations'; +import { MINUTE, SECOND } from './util/durations'; const MAX_MESSAGE_BODY_LENGTH = 64 * 1024; @@ -863,7 +863,7 @@ export class ConversationController { } const queue = new PQueue({ concurrency: 3, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); queue.addAll( diff --git a/ts/SignalProtocolStore.ts b/ts/SignalProtocolStore.ts index 93609d60f76..cf96c7230a1 100644 --- a/ts/SignalProtocolStore.ts +++ b/ts/SignalProtocolStore.ts @@ -53,6 +53,7 @@ import * as log from './logging/log'; import { singleProtoJobQueue } from './jobs/singleProtoJobQueue'; import * as Errors from './types/errors'; import MessageSender from './textsecure/SendMessage'; +import { MINUTE } from './util/durations'; const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds @@ -533,7 +534,7 @@ export class SignalProtocolStore extends EventsMixin { private _createSenderKeyQueue(): PQueue { return new PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); } @@ -702,7 +703,7 @@ export class SignalProtocolStore extends EventsMixin { private _createSessionQueue(): PQueue { return new PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); } diff --git a/ts/background.ts b/ts/background.ts index 79605dbb10d..8fe15f91008 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -428,7 +428,7 @@ export async function startApp(): Promise { const eventHandlerQueue = new window.PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: durations.MINUTE * 30, }); const profileKeyResponseQueue = new window.PQueue(); @@ -446,7 +446,7 @@ export async function startApp(): Promise { window.Whisper.deliveryReceiptQueue = new window.PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: durations.MINUTE * 30, }); window.Whisper.deliveryReceiptQueue.pause(); window.Whisper.deliveryReceiptBatcher = diff --git a/ts/components/emoji/lib.ts b/ts/components/emoji/lib.ts index c11fc9478f5..800d06cbdf5 100644 --- a/ts/components/emoji/lib.ts +++ b/ts/components/emoji/lib.ts @@ -22,6 +22,7 @@ import PQueue from 'p-queue'; import is from '@sindresorhus/is'; import { getOwn } from '../../util/getOwn'; import * as log from '../../logging/log'; +import { MINUTE } from '../../util/durations'; export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']; @@ -102,7 +103,7 @@ const makeImagePath = (src: string) => { const imageQueue = new PQueue({ concurrency: 10, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); const images = new Set(); diff --git a/ts/indexeddb.ts b/ts/indexeddb.ts index 19f1f3ab006..ecc2db60d7c 100644 --- a/ts/indexeddb.ts +++ b/ts/indexeddb.ts @@ -44,9 +44,23 @@ export async function doesDatabaseExist(): Promise { }); } -export function removeDatabase(): void { - window.SignalContext.log.info( - `Deleting IndexedDB database '${LEGACY_DATABASE_ID}'` - ); - window.indexedDB.deleteDatabase(LEGACY_DATABASE_ID); +export function removeDatabase(): Promise { + return new Promise((resolve, reject) => { + window.SignalContext.log.info( + `removeDatabase: Deleting IndexedDB database '${LEGACY_DATABASE_ID}'` + ); + const request = window.indexedDB.deleteDatabase(LEGACY_DATABASE_ID); + request.onerror = () => { + window.SignalContext.log.error( + 'removeDatabase: Error deleting database.' + ); + reject(new Error('Error deleting database')); + }; + request.onsuccess = () => { + window.SignalContext.log.info( + 'removeDatabase: Database deleted successfully' + ); + resolve(); + }; + }); } diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index e5e967d2565..058a7863b76 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -1384,7 +1384,7 @@ export class ConversationModel extends window.Backbone if (!this.newMessageQueue) { this.newMessageQueue = new window.PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: durations.MINUTE * 30, }); } diff --git a/ts/routineProfileRefresh.ts b/ts/routineProfileRefresh.ts index 9ec9e8f716c..2982260d0ec 100644 --- a/ts/routineProfileRefresh.ts +++ b/ts/routineProfileRefresh.ts @@ -13,6 +13,7 @@ import { isOlderThan } from './util/timestamp'; import type { ConversationModel } from './models/conversations'; import type { StorageInterface } from './types/Storage.d'; import { getProfile } from './util/getProfile'; +import { MINUTE } from './util/durations'; const STORAGE_KEY = 'lastAttemptedToRefreshProfilesAt'; const MAX_AGE_TO_BE_CONSIDERED_ACTIVE = 30 * 24 * 60 * 60 * 1000; @@ -77,7 +78,7 @@ export async function routineProfileRefresh({ const refreshQueue = new PQueue({ concurrency: 5, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); for (const conversation of conversationsToRefresh) { diff --git a/ts/sql/Client.ts b/ts/sql/Client.ts index 7aa58405aa1..69903fa5f0b 100644 --- a/ts/sql/Client.ts +++ b/ts/sql/Client.ts @@ -89,6 +89,7 @@ import type { } from './Interface'; import Server from './Server'; import { isCorruptionError } from './errors'; +import { MINUTE } from '../util/durations'; // We listen to a lot of events on ipc, often on the same channel. This prevents // any warnings that might be sent to the console in that case. @@ -1407,7 +1408,7 @@ async function removeAllMessagesInConversation( log.info(`removeAllMessagesInConversation/${logId}: Cleanup...`); // Note: It's very important that these models are fully hydrated because // we need to delete all associated on-disk files along with the database delete. - const queue = new window.PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 }); + const queue = new window.PQueue({ concurrency: 3, timeout: MINUTE * 30 }); queue.addAll( messages.map( (message: MessageType) => async () => cleanupMessage(message) diff --git a/ts/textsecure/TaskWithTimeout.ts b/ts/textsecure/TaskWithTimeout.ts index 8890f036851..3f163a3798b 100644 --- a/ts/textsecure/TaskWithTimeout.ts +++ b/ts/textsecure/TaskWithTimeout.ts @@ -36,7 +36,7 @@ export default function createTaskWithTimeout>( id: string, options: { timeout?: number } = {} ): (...args: Args) => Promise { - const timeout = options.timeout || 2 * durations.MINUTE; + const timeout = options.timeout || 30 * durations.MINUTE; const timeoutError = new Error(`${id || ''} task did not complete in time.`); diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index a966d143eb7..a463e76e293 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -2292,7 +2292,7 @@ export function initialize({ // Upload stickers const queue = new PQueue({ concurrency: 3, - timeout: 1000 * 60 * 2, + timeout: durations.MINUTE * 30, throwOnTimeout: true, }); await Promise.all( diff --git a/ts/types/Stickers.ts b/ts/types/Stickers.ts index 97fdb0d1705..ad52350df65 100644 --- a/ts/types/Stickers.ts +++ b/ts/types/Stickers.ts @@ -25,6 +25,7 @@ import Data from '../sql/Client'; import { SignalService as Proto } from '../protobuf'; import * as log from '../logging/log'; import type { StickersStateType } from '../state/ducks/stickers'; +import { MINUTE } from '../util/durations'; export type StickerType = { packId: string; @@ -101,7 +102,7 @@ const VALID_PACK_ID_REGEXP = /^[0-9a-f]{32}$/i; let initialState: StickersStateType | undefined; let packsToDownload: DownloadMap | undefined; -const downloadQueue = new Queue({ concurrency: 1, timeout: 1000 * 60 * 2 }); +const downloadQueue = new Queue({ concurrency: 1, timeout: MINUTE * 30 }); export async function load(): Promise { const [packs, recentStickers] = await Promise.all([ diff --git a/ts/util/batcher.ts b/ts/util/batcher.ts index d177859623f..9401325e539 100644 --- a/ts/util/batcher.ts +++ b/ts/util/batcher.ts @@ -7,6 +7,7 @@ import { sleep } from './sleep'; import * as log from '../logging/log'; import * as Errors from '../types/errors'; import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary'; +import { MINUTE } from './durations'; declare global { // We want to extend `window`'s properties, so we need an interface. @@ -56,7 +57,7 @@ export function createBatcher( let items: Array = []; const queue = new PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); diff --git a/ts/util/callingTones.ts b/ts/util/callingTones.ts index 7942a2fce7e..c4d45d8a5c2 100644 --- a/ts/util/callingTones.ts +++ b/ts/util/callingTones.ts @@ -2,11 +2,12 @@ // SPDX-License-Identifier: AGPL-3.0-only import PQueue from 'p-queue'; +import { MINUTE } from './durations'; import { Sound } from './Sound'; const ringtoneEventQueue = new PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, }); diff --git a/ts/util/sendToGroup.ts b/ts/util/sendToGroup.ts index 41b8dcd1b2c..1094e0a1fa9 100644 --- a/ts/util/sendToGroup.ts +++ b/ts/util/sendToGroup.ts @@ -59,6 +59,7 @@ import { SignalService as Proto } from '../protobuf'; import { strictAssert } from './assert'; import * as log from '../logging/log'; import { GLOBAL_ZONE } from '../SignalProtocolStore'; +import { MINUTE } from './durations'; const ERROR_EXPIRED_OR_MISSING_DEVICES = 409; const ERROR_STALE_DEVICES = 410; @@ -814,7 +815,7 @@ export async function _waitForAll({ }): Promise> { const queue = new PQueue({ concurrency: maxConcurrency, - timeout: 2 * 60 * 1000, + timeout: MINUTE * 30, throwOnTimeout: true, }); return queue.addAll(tasks); diff --git a/ts/util/waitBatcher.ts b/ts/util/waitBatcher.ts index 25acf2a76a6..5653e049020 100644 --- a/ts/util/waitBatcher.ts +++ b/ts/util/waitBatcher.ts @@ -7,6 +7,7 @@ import { sleep } from './sleep'; import * as log from '../logging/log'; import * as Errors from '../types/errors'; import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary'; +import { MINUTE } from './durations'; declare global { // We want to extend `window`'s properties, so we need an interface. @@ -80,7 +81,7 @@ export function createWaitBatcher( let items: Array> = []; const queue = new PQueue({ concurrency: 1, - timeout: 1000 * 60 * 2, + timeout: MINUTE * 30, throwOnTimeout: true, });