Update attachment download handling while in a call

This commit is contained in:
trevor-signal 2024-04-19 13:09:51 -04:00 committed by GitHub
parent a51962e9b9
commit d0d49a043f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 26 deletions

View file

@ -243,7 +243,7 @@ export class AttachmentDownloadManager {
return { return {
...attachment, ...attachment,
pending: true, pending: !this.shouldHoldOffOnStartingQueuedJobs(),
}; };
} }
@ -300,13 +300,6 @@ export class AttachmentDownloadManager {
return; return;
} }
if (this.isInCall()) {
log.info(
'AttachmentDownloadManager/_maybeStartJobs: holding off on starting new jobs; in call'
);
return;
}
const numJobsToStart = this.getMaximumNumberOfJobsToStart(); const numJobsToStart = this.getMaximumNumberOfJobsToStart();
if (numJobsToStart <= 0) { if (numJobsToStart <= 0) {
@ -323,6 +316,17 @@ export class AttachmentDownloadManager {
timestamp: Date.now(), timestamp: Date.now(),
}); });
if (nextJobs.length === 0) {
return;
}
if (this.shouldHoldOffOnStartingQueuedJobs()) {
log.info(
`AttachmentDownloadManager/_maybeStartJobs: holding off on starting ${nextJobs.length} new job(s)`
);
return;
}
// TODO (DESKTOP-6913): if a prioritized job is selected, we will to update the // TODO (DESKTOP-6913): if a prioritized job is selected, we will to update the
// in-memory job with that information so we can handle it differently, including // in-memory job with that information so we can handle it differently, including
// e.g. downloading a thumbnail before the full-size version // e.g. downloading a thumbnail before the full-size version
@ -395,6 +399,7 @@ export class AttachmentDownloadManager {
lastAttemptTimestamp: now, lastAttemptTimestamp: now,
}); });
} }
private getActiveJobCount(): number { private getActiveJobCount(): number {
return this.activeJobs.size; return this.activeJobs.size;
} }
@ -428,7 +433,7 @@ export class AttachmentDownloadManager {
if (this.isJobRunning(job)) { if (this.isJobRunning(job)) {
const jobIdForLogging = getJobIdForLogging(job); const jobIdForLogging = getJobIdForLogging(job);
log.warn( log.warn(
`attachmentDownloads/_addRunningJob: job ${jobIdForLogging} is already running` `AttachmentDownloadManager/addRunningJob: job ${jobIdForLogging} is already running`
); );
} }
this.activeJobs.set(this.getJobId(job), { this.activeJobs.set(this.getJobId(job), {
@ -452,6 +457,10 @@ export class AttachmentDownloadManager {
return `${messageId}.${attachmentType}.${digest}`; return `${messageId}.${attachmentType}.${digest}`;
} }
private shouldHoldOffOnStartingQueuedJobs(): boolean {
return this.isInCall();
}
// Static methods // Static methods
static get instance(): AttachmentDownloadManager { static get instance(): AttachmentDownloadManager {
if (!AttachmentDownloadManager._instance) { if (!AttachmentDownloadManager._instance) {
@ -488,7 +497,7 @@ async function runDownloadAttachmentJob(
isLastAttempt: boolean isLastAttempt: boolean
): Promise<JobResultType> { ): Promise<JobResultType> {
const jobIdForLogging = getJobIdForLogging(job); const jobIdForLogging = getJobIdForLogging(job);
const logId = `attachment_downloads/runDownloadAttachmentJob/${jobIdForLogging}`; const logId = `AttachmentDownloadManager/runDownloadAttachmentJob/${jobIdForLogging}`;
const message = await __DEPRECATED$getMessageById(job.messageId); const message = await __DEPRECATED$getMessageById(job.messageId);
@ -511,6 +520,7 @@ async function runDownloadAttachmentJob(
await addAttachmentToMessage( await addAttachmentToMessage(
message, message,
_markAttachmentAsTooBig(job.attachment), _markAttachmentAsTooBig(job.attachment),
logId,
{ type: job.attachmentType } { type: job.attachmentType }
); );
return { status: 'finished' }; return { status: 'finished' };
@ -520,6 +530,7 @@ async function runDownloadAttachmentJob(
await addAttachmentToMessage( await addAttachmentToMessage(
message, message,
_markAttachmentAsPermanentlyErrored(job.attachment), _markAttachmentAsPermanentlyErrored(job.attachment),
logId,
{ type: job.attachmentType } { type: job.attachmentType }
); );
@ -530,6 +541,7 @@ async function runDownloadAttachmentJob(
await addAttachmentToMessage( await addAttachmentToMessage(
message, message,
_markAttachmentAsTransientlyErrored(job.attachment), _markAttachmentAsTransientlyErrored(job.attachment),
logId,
{ type: job.attachmentType } { type: job.attachmentType }
); );
return { status: 'finished' }; return { status: 'finished' };
@ -542,6 +554,7 @@ async function runDownloadAttachmentJob(
...job.attachment, ...job.attachment,
pending: false, pending: false,
}, },
logId,
{ type: job.attachmentType } { type: job.attachmentType }
); );
return { status: 'retry' }; return { status: 'retry' };
@ -561,7 +574,7 @@ async function runDownloadAttachmentJobInner(
const { messageId, attachment, attachmentType: type } = job; const { messageId, attachment, attachmentType: type } = job;
const jobIdForLogging = getJobIdForLogging(job); const jobIdForLogging = getJobIdForLogging(job);
const logId = `attachment_downloads/_runDownloadJobInner(${jobIdForLogging})`; const logId = `AttachmentDownloadManager/runDownloadJobInner(${jobIdForLogging})`;
if (!job || !attachment || !messageId) { if (!job || !attachment || !messageId) {
throw new Error(`${logId}: Key information required for job was missing.`); throw new Error(`${logId}: Key information required for job was missing.`);
@ -590,6 +603,7 @@ async function runDownloadAttachmentJobInner(
await addAttachmentToMessage( await addAttachmentToMessage(
message, message,
{ ...attachment, pending: true }, { ...attachment, pending: true },
logId,
{ type } { type }
); );
@ -601,6 +615,7 @@ async function runDownloadAttachmentJobInner(
await addAttachmentToMessage( await addAttachmentToMessage(
message, message,
omit(upgradedAttachment, ['error', 'pending']), omit(upgradedAttachment, ['error', 'pending']),
logId,
{ {
type, type,
} }

View file

@ -11,13 +11,14 @@ import { getAttachmentSignature, isDownloaded } from '../types/Attachment';
export async function addAttachmentToMessage( export async function addAttachmentToMessage(
message: MessageModel | null | undefined, message: MessageModel | null | undefined,
attachment: AttachmentType, attachment: AttachmentType,
jobLogId: string,
{ type }: { type: AttachmentDownloadJobTypeType } { type }: { type: AttachmentDownloadJobTypeType }
): Promise<void> { ): Promise<void> {
if (!message) { if (!message) {
return; return;
} }
const logPrefix = `${message.idForLogging()} (type: ${type})`; const logPrefix = `${jobLogId}/addAttachmentToMessage`;
const attachmentSignature = getAttachmentSignature(attachment); const attachmentSignature = getAttachmentSignature(attachment);
if (type === 'long-message') { if (type === 'long-message') {

View file

@ -47,7 +47,6 @@ import { isAciString } from '../util/isAciString';
import * as reactionUtil from '../reactions/util'; import * as reactionUtil from '../reactions/util';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import type { AttachmentType } from '../types/Attachment'; import type { AttachmentType } from '../types/Attachment';
import { isImage, isVideo } from '../types/Attachment';
import * as MIME from '../types/MIME'; import * as MIME from '../types/MIME';
import { ReadStatus } from '../messages/MessageReadStatus'; import { ReadStatus } from '../messages/MessageReadStatus';
import type { SendStateByConversationId } from '../messages/MessageSendState'; import type { SendStateByConversationId } from '../messages/MessageSendState';
@ -96,7 +95,6 @@ import {
isTitleTransitionNotification, isTitleTransitionNotification,
} from '../state/selectors/message'; } from '../state/selectors/message';
import type { ReactionAttributesType } from '../messageModifiers/Reactions'; import type { ReactionAttributesType } from '../messageModifiers/Reactions';
import { isInCall } from '../state/selectors/calling';
import { ReactionSource } from '../reactions/ReactionSource'; import { ReactionSource } from '../reactions/ReactionSource';
import * as LinkPreview from '../types/LinkPreview'; import * as LinkPreview from '../types/LinkPreview';
import { SignalService as Proto } from '../protobuf'; import { SignalService as Proto } from '../protobuf';
@ -2371,23 +2369,18 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// Only queue attachments for downloads if this is a story (with additional logic), or // Only queue attachments for downloads if this is a story (with additional logic), or
// if it's either an outgoing message or we've accepted the conversation // if it's either an outgoing message or we've accepted the conversation
let shouldDownloadNow = false; let shouldQueueForDownload = false;
const attachments = this.get('attachments') || [];
const reduxState = window.reduxStore.getState();
if (isStory(this.attributes)) { if (isStory(this.attributes)) {
shouldDownloadNow = await shouldDownloadStory(conversation.attributes); shouldQueueForDownload = await shouldDownloadStory(
conversation.attributes
);
} else { } else {
const isVisualMediaAndUserInCall = shouldQueueForDownload =
isInCall(reduxState) && (isImage(attachments) || isVideo(attachments));
shouldDownloadNow =
this.hasAttachmentDownloads() && this.hasAttachmentDownloads() &&
(conversation.getAccepted() || isOutgoing(this.attributes)) && (conversation.getAccepted() || isOutgoing(this.attributes));
!isVisualMediaAndUserInCall;
} }
if (shouldDownloadNow) { if (shouldQueueForDownload) {
if (shouldUseAttachmentDownloadQueue()) { if (shouldUseAttachmentDownloadQueue()) {
addToAttachmentDownloadQueue(idLog, this); addToAttachmentDownloadQueue(idLog, this);
} else { } else {