Skip to content

Commit

Permalink
avoid keeping a reference to the file chunk in ChunkWorker
Browse files Browse the repository at this point in the history
When the Worker actor loops over a file, it does not always deallocate
file chunks until the loop completes.

Because each ChunkWorker is intended to be only used once, it is not
necessary to keep a reference to its file chunk beyond the upload task
call.
  • Loading branch information
andrewjl-mux committed Mar 6, 2024
1 parent 8d9936f commit ee8d7cb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
36 changes: 22 additions & 14 deletions Sources/MuxUploadSDK/Upload/ChunkWorker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

import Foundation

/// Uploads a single chunk. Starts an internal Task on creation, which you can get with ``getTask``
/// This class takes care of retries and backoff on a per-chunk basis
/// This class provides no thread safety to the outside world
/// Uploads a single chunk. Starts an internal Task on creation,
/// which can be accessed with ``makeUploadTaskIfNeeded``.
///
/// This class takes care of retries and backoff on a per-chunk basis
/// This class provides no thread safety to the outside world
class ChunkWorker {
let uploadURL: URL
let chunk: FileChunk
let maxRetries: Int
let chunkProgress: Progress

Expand All @@ -33,11 +34,12 @@ class ChunkWorker {
self.progressDelegate = delegatePair
}

func getTask() -> Task<Success, Error> {

func makeUploadTaskIfNeeded(
chunk: FileChunk
) -> Task<Success, Error> {
guard let uploadTask else {
chunkStartTime = Date().timeIntervalSince1970
let uploadTask = makeUploadTask()
let uploadTask = makeUploadTask(chunk: chunk)
self.uploadTask = uploadTask
return uploadTask
}
Expand All @@ -51,12 +53,14 @@ class ChunkWorker {
}
}

private func makeUploadTask() -> Task<Success, Error> {
private func makeUploadTask(
chunk: FileChunk
) -> Task<Success, Error> {
return Task { [self] in
var retries = 0
var requestError: Error?
let repsonseValidator = ChunkResponseValidator()

repeat {
do {
let chunkActor = ChunkActor(
Expand Down Expand Up @@ -145,21 +149,25 @@ class ChunkWorker {
struct Success : Sendable {
let finalState: Update
let tries: Int
// TODO: Also AF Response
}

convenience init(uploadInfo: UploadInfo, fileChunk: FileChunk, chunkProgress: Progress) {
convenience init(
uploadInfo: UploadInfo,
chunkProgress: Progress
) {
self.init(
uploadURL: uploadInfo.uploadURL,
fileChunk: fileChunk,
chunkProgress: chunkProgress,
maxRetries: uploadInfo.options.transport.retryLimitPerChunk
)
}

init(uploadURL: URL, fileChunk: FileChunk, chunkProgress: Progress, maxRetries: Int) {
init(
uploadURL: URL,
chunkProgress: Progress,
maxRetries: Int
) {
self.uploadURL = uploadURL
self.chunk = fileChunk
self.maxRetries = maxRetries
self.chunkProgress = chunkProgress
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/MuxUploadSDK/Upload/ChunkedFileUploader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -449,11 +449,9 @@ fileprivate actor Worker {

let wideChunkSize = Int64(chunk.size())
let chunkProgress = Progress(totalUnitCount: wideChunkSize)
//overallProgress.addChild(chunkProgress, withPendingUnitCount: wideChunkSize)

let chunkWorker = ChunkWorker(
uploadURL: uploadInfo.uploadURL,
fileChunk: chunk,
chunkProgress: chunkProgress,
maxRetries: uploadInfo.options.transport.retryLimitPerChunk
)
Expand All @@ -470,7 +468,9 @@ fileprivate actor Worker {
// Problem is in line bellow, task will retain the reference to a chunk read from file and will
// not release it until the for loop is exited, we need to find a way to implicitly release task memory
// withouth breaking the for loop.
let chunkResult = try await chunkWorker.getTask().value
let chunkResult = try await chunkWorker.makeUploadTaskIfNeeded(
chunk: chunk
).value
SDKLogger.logger?.info("Completed Chunk:\n \(String(describing: chunkResult))")
} while (readBytes == uploadInfo.options.transport.chunkSizeInBytes)

Expand Down

0 comments on commit ee8d7cb

Please sign in to comment.