forked from signalapp/Signal-Desktop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Retry delivery and read receipts for up to 24 hours
- Loading branch information
1 parent
e81821f
commit f9e9883
Showing
15 changed files
with
316 additions
and
243 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2021 Signal Messenger, LLC | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import { z } from 'zod'; | ||
import type { LoggerType } from '../types/Logging'; | ||
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff'; | ||
import { receiptSchema, ReceiptType } from '../types/Receipt'; | ||
import { MAX_RETRY_TIME, runReceiptJob } from './helpers/receiptHelpers'; | ||
|
||
import { JobQueue } from './JobQueue'; | ||
import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; | ||
|
||
const deliveryReceiptsJobDataSchema = z.object({ | ||
deliveryReceipts: receiptSchema.array(), | ||
}); | ||
|
||
type DeliveryReceiptsJobData = z.infer<typeof deliveryReceiptsJobDataSchema>; | ||
|
||
export class DeliveryReceiptsJobQueue extends JobQueue<DeliveryReceiptsJobData> { | ||
protected parseData(data: unknown): DeliveryReceiptsJobData { | ||
return deliveryReceiptsJobDataSchema.parse(data); | ||
} | ||
|
||
protected async run( | ||
{ | ||
data, | ||
timestamp, | ||
}: Readonly<{ data: DeliveryReceiptsJobData; timestamp: number }>, | ||
{ attempt, log }: Readonly<{ attempt: number; log: LoggerType }> | ||
): Promise<void> { | ||
await runReceiptJob({ | ||
attempt, | ||
log, | ||
timestamp, | ||
receipts: data.deliveryReceipts, | ||
type: ReceiptType.Delivery, | ||
}); | ||
} | ||
} | ||
|
||
export const deliveryReceiptsJobQueue = new DeliveryReceiptsJobQueue({ | ||
store: jobQueueDatabaseStore, | ||
queueType: 'delivery receipts', | ||
maxAttempts: exponentialBackoffMaxAttempts(MAX_RETRY_TIME), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2021 Signal Messenger, LLC | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import * as durations from '../../util/durations'; | ||
import type { LoggerType } from '../../types/Logging'; | ||
import type { Receipt, ReceiptType } from '../../types/Receipt'; | ||
import { sendReceipts } from '../../util/sendReceipts'; | ||
import { commonShouldJobContinue } from './commonShouldJobContinue'; | ||
import { handleCommonJobRequestError } from './handleCommonJobRequestError'; | ||
|
||
export const MAX_RETRY_TIME = durations.DAY; | ||
|
||
export async function runReceiptJob({ | ||
attempt, | ||
log, | ||
timestamp, | ||
receipts, | ||
type, | ||
}: Readonly<{ | ||
attempt: number; | ||
log: LoggerType; | ||
receipts: ReadonlyArray<Receipt>; | ||
timestamp: number; | ||
type: ReceiptType; | ||
}>): Promise<void> { | ||
const timeRemaining = timestamp + MAX_RETRY_TIME - Date.now(); | ||
|
||
const shouldContinue = await commonShouldJobContinue({ | ||
attempt, | ||
log, | ||
timeRemaining, | ||
}); | ||
if (!shouldContinue) { | ||
return; | ||
} | ||
|
||
try { | ||
await sendReceipts({ log, receipts, type }); | ||
} catch (err: unknown) { | ||
await handleCommonJobRequestError({ err, log, timeRemaining }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright 2021 Signal Messenger, LLC | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import { z } from 'zod'; | ||
import type { LoggerType } from '../types/Logging'; | ||
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff'; | ||
import type { StorageInterface } from '../types/Storage.d'; | ||
import type { Receipt } from '../types/Receipt'; | ||
import { receiptSchema, ReceiptType } from '../types/Receipt'; | ||
import { MAX_RETRY_TIME, runReceiptJob } from './helpers/receiptHelpers'; | ||
|
||
import { JobQueue } from './JobQueue'; | ||
import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; | ||
|
||
const readReceiptsJobDataSchema = z.object({ | ||
readReceipts: receiptSchema.array(), | ||
}); | ||
|
||
type ReadReceiptsJobData = z.infer<typeof readReceiptsJobDataSchema>; | ||
|
||
export class ReadReceiptsJobQueue extends JobQueue<ReadReceiptsJobData> { | ||
public async addIfAllowedByUser( | ||
storage: Pick<StorageInterface, 'get'>, | ||
readReceipts: Array<Receipt> | ||
): Promise<void> { | ||
if (storage.get('read-receipt-setting')) { | ||
await this.add({ readReceipts }); | ||
} | ||
} | ||
|
||
protected parseData(data: unknown): ReadReceiptsJobData { | ||
return readReceiptsJobDataSchema.parse(data); | ||
} | ||
|
||
protected async run( | ||
{ | ||
data, | ||
timestamp, | ||
}: Readonly<{ data: ReadReceiptsJobData; timestamp: number }>, | ||
{ attempt, log }: Readonly<{ attempt: number; log: LoggerType }> | ||
): Promise<void> { | ||
await runReceiptJob({ | ||
attempt, | ||
log, | ||
timestamp, | ||
receipts: data.readReceipts, | ||
type: ReceiptType.Read, | ||
}); | ||
} | ||
} | ||
|
||
export const readReceiptsJobQueue = new ReadReceiptsJobQueue({ | ||
store: jobQueueDatabaseStore, | ||
queueType: 'read receipts', | ||
maxAttempts: exponentialBackoffMaxAttempts(MAX_RETRY_TIME), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.