Skip to content

Commit ee8d7cb

Browse files
committed
avoid keeping a reference to the file chunk in ChunkWorker
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.
1 parent 8d9936f commit ee8d7cb

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

Sources/MuxUploadSDK/Upload/ChunkWorker.swift

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77

88
import Foundation
99

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

@@ -33,11 +34,12 @@ class ChunkWorker {
3334
self.progressDelegate = delegatePair
3435
}
3536

36-
func getTask() -> Task<Success, Error> {
37-
37+
func makeUploadTaskIfNeeded(
38+
chunk: FileChunk
39+
) -> Task<Success, Error> {
3840
guard let uploadTask else {
3941
chunkStartTime = Date().timeIntervalSince1970
40-
let uploadTask = makeUploadTask()
42+
let uploadTask = makeUploadTask(chunk: chunk)
4143
self.uploadTask = uploadTask
4244
return uploadTask
4345
}
@@ -51,12 +53,14 @@ class ChunkWorker {
5153
}
5254
}
5355

54-
private func makeUploadTask() -> Task<Success, Error> {
56+
private func makeUploadTask(
57+
chunk: FileChunk
58+
) -> Task<Success, Error> {
5559
return Task { [self] in
5660
var retries = 0
5761
var requestError: Error?
5862
let repsonseValidator = ChunkResponseValidator()
59-
63+
6064
repeat {
6165
do {
6266
let chunkActor = ChunkActor(
@@ -145,21 +149,25 @@ class ChunkWorker {
145149
struct Success : Sendable {
146150
let finalState: Update
147151
let tries: Int
148-
// TODO: Also AF Response
149152
}
150153

151-
convenience init(uploadInfo: UploadInfo, fileChunk: FileChunk, chunkProgress: Progress) {
154+
convenience init(
155+
uploadInfo: UploadInfo,
156+
chunkProgress: Progress
157+
) {
152158
self.init(
153159
uploadURL: uploadInfo.uploadURL,
154-
fileChunk: fileChunk,
155160
chunkProgress: chunkProgress,
156161
maxRetries: uploadInfo.options.transport.retryLimitPerChunk
157162
)
158163
}
159164

160-
init(uploadURL: URL, fileChunk: FileChunk, chunkProgress: Progress, maxRetries: Int) {
165+
init(
166+
uploadURL: URL,
167+
chunkProgress: Progress,
168+
maxRetries: Int
169+
) {
161170
self.uploadURL = uploadURL
162-
self.chunk = fileChunk
163171
self.maxRetries = maxRetries
164172
self.chunkProgress = chunkProgress
165173
}

Sources/MuxUploadSDK/Upload/ChunkedFileUploader.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,11 +449,9 @@ fileprivate actor Worker {
449449

450450
let wideChunkSize = Int64(chunk.size())
451451
let chunkProgress = Progress(totalUnitCount: wideChunkSize)
452-
//overallProgress.addChild(chunkProgress, withPendingUnitCount: wideChunkSize)
453452

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

0 commit comments

Comments
 (0)