Fix resource leaks when uploading backup attachments.

This commit is contained in:
jeffrey-signal
2025-06-12 10:29:29 -04:00
committed by Michelle Tang
parent 4a1baa75a8
commit eb620374e2
2 changed files with 33 additions and 25 deletions

View File

@@ -8,7 +8,6 @@ package org.thoughtcrime.securesms.jobs
import android.os.Build
import org.signal.core.util.logging.Log
import org.signal.protos.resumableuploads.ResumableUpload
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.attachments.AttachmentId
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
import org.thoughtcrime.securesms.attachments.PointerAttachment
@@ -116,25 +115,28 @@ class ArchiveThumbnailUploadJob private constructor(
Log.d(TAG, "Got an upload spec!")
specResult.result.toProto()
}
is NetworkResult.ApplicationError -> {
Log.w(TAG, "Failed to get an upload spec due to an application error. Retrying.", specResult.throwable)
return Result.retry(defaultBackoff())
}
is NetworkResult.NetworkError -> {
Log.w(TAG, "Encountered a transient network error when getting upload spec. Retrying.")
return Result.retry(defaultBackoff())
}
is NetworkResult.StatusCodeError -> {
Log.w(TAG, "Failed to get an upload spec with status code ${specResult.code}")
return Result.retry(defaultBackoff())
}
}
val stream = buildSignalServiceAttachmentStream(thumbnailResult, resumableUpload)
val attachmentPointer: Attachment = try {
val pointer = AppDependencies.signalServiceMessageSender.uploadAttachment(stream)
PointerAttachment.forPointer(Optional.of(pointer)).get()
val attachmentPointer = try {
buildSignalServiceAttachmentStream(thumbnailResult, resumableUpload).use { stream ->
val pointer = AppDependencies.signalServiceMessageSender.uploadAttachment(stream)
PointerAttachment.forPointer(Optional.of(pointer)).get()
}
} catch (e: IOException) {
Log.w(TAG, "Failed to upload attachment", e)
return Result.retry(defaultBackoff())
@@ -152,14 +154,17 @@ class ArchiveThumbnailUploadJob private constructor(
Log.d(TAG, "Successfully archived thumbnail for $attachmentId mediaName=${attachment.requireThumbnailMediaName()}")
Result.success()
}
is NetworkResult.NetworkError -> {
Log.w(TAG, "Hit a network error when trying to archive thumbnail for $attachmentId", result.exception)
Result.retry(defaultBackoff())
}
is NetworkResult.StatusCodeError -> {
Log.w(TAG, "Hit a status code error of ${result.code} when trying to archive thumbnail for $attachmentId")
Result.retry(defaultBackoff())
}
is NetworkResult.ApplicationError -> Result.fatalFailure(RuntimeException(result.throwable))
}
}

View File

@@ -186,30 +186,33 @@ class UploadAttachmentToArchiveJob private constructor(
Log.d(TAG, "[$attachmentId] Beginning upload...")
progressServiceController.use {
val uploadResult: AttachmentUploadResult = when (val result = SignalNetwork.attachments.uploadAttachmentV4(attachmentStream)) {
is NetworkResult.Success -> result.result
is NetworkResult.ApplicationError -> throw result.throwable
is NetworkResult.NetworkError -> {
Log.w(TAG, "[$attachmentId] Failed to upload due to network error.", result.exception)
val uploadResult: AttachmentUploadResult = attachmentStream.use { managedAttachmentStream ->
when (val result = SignalNetwork.attachments.uploadAttachmentV4(managedAttachmentStream)) {
is NetworkResult.Success -> result.result
is NetworkResult.ApplicationError -> throw result.throwable
is NetworkResult.NetworkError -> {
Log.w(TAG, "[$attachmentId] Failed to upload due to network error.", result.exception)
if (result.exception.cause is ProtocolException) {
Log.w(TAG, "[$attachmentId] Length may be incorrect. Recalculating.", result.exception)
if (result.exception.cause is ProtocolException) {
Log.w(TAG, "[$attachmentId] Length may be incorrect. Recalculating.", result.exception)
val actualLength = SignalDatabase.attachments.getAttachmentStream(attachmentId, 0).readLength()
if (actualLength != attachment.size) {
Log.w(TAG, "[$attachmentId] Length was incorrect! Will update. Previous: ${attachment.size}, Newly-Calculated: $actualLength", result.exception)
SignalDatabase.attachments.updateAttachmentLength(attachmentId, actualLength)
} else {
Log.i(TAG, "[$attachmentId] Length was correct. No action needed. Will retry.")
val actualLength = SignalDatabase.attachments.getAttachmentStream(attachmentId, 0)
.use { it.readLength() }
if (actualLength != attachment.size) {
Log.w(TAG, "[$attachmentId] Length was incorrect! Will update. Previous: ${attachment.size}, Newly-Calculated: $actualLength", result.exception)
SignalDatabase.attachments.updateAttachmentLength(attachmentId, actualLength)
} else {
Log.i(TAG, "[$attachmentId] Length was correct. No action needed. Will retry.")
}
}
return Result.retry(defaultBackoff())
}
return Result.retry(defaultBackoff())
}
is NetworkResult.StatusCodeError -> {
Log.w(TAG, "[$attachmentId] Failed to upload due to status code error. Code: ${result.code}", result.exception)
return Result.retry(defaultBackoff())
is NetworkResult.StatusCodeError -> {
Log.w(TAG, "[$attachmentId] Failed to upload due to status code error. Code: ${result.code}", result.exception)
return Result.retry(defaultBackoff())
}
}
}