Search code examples
iosamazon-web-servicesaws-amplifyaws-sdk-iosawss3transferutility

AWSS3TransferUtility: How to retry failed upload task after app restart


I want to retry previously failed S3 upload tasks after app restart. On app init, I call

    // register a transfer utility object asynchronously
    AWSS3TransferUtility.register(
        with: configuration!,
        transferUtilityConfiguration: tuConf,
        forKey: "..." // redacted
    ) { (error) in
         if let error = error {
             // handle registration error.
            Logging.logError("Error in registration: \(error)")
         } else {
            Logging.logDebug("AWS S3 TransferUtility registration success, now check for pending tasks")
            DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
                finishPendingTasks()
            }
        }
    }

And here is the function to finish pending tasks

  static func finishPendingTasks() {
    let transferUtility = AWSS3TransferUtility.default()
    let uploadTasks = transferUtility.getUploadTasks().result

    Logging.logDebug("Finish pending AWS upload tasks")
    var progressBlock: AWSS3TransferUtilityProgressBlock?
    progressBlock = {(task, progress) in
        DispatchQueue.main.async(execute: {
            // Do something e.g. Update a progress bar.
            Logging.logDebug("upload in process \(progress)")
        })
    }

    var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
    completionHandler = { (task, error) -> Void in
        DispatchQueue.main.async(execute: {
            // Do something e.g. Alert a user for transfer completion.
            // On failed uploads, `error` contains the error object.
            Logging.logDebug("upload completed1 \(task.bucket)")
            Logging.logDebug("upload completed2 \(String(describing: task.response))")
            Logging.logDebug("upload completed3 \(task.key)")
            Logging.logDebug("upload error \(String(describing: error))")
        })
    }

    let taskCount = uploadTasks?.count ?? 0
    Logging.logDebug("Number of upload tasks: \(taskCount)")
    for task in uploadTasks! {
        if let awsTask = task as? AWSS3TransferUtilityUploadTask {
            Logging.logDebug("Resuming uploading task key \(awsTask.key), transfer ID: \(awsTask.transferID), status: \(awsTask.status.rawValue)")
            awsTask.setCompletionHandler(completionHandler!)
            awsTask.setProgressBlock(progressBlock!)
            awsTask.resume() // <------- HAS NO EFFECT!
        }
    }
}

Status rawValue is 0

Not sure if resume() is what triggers the retry. Is there a procedure documented somewhere?

Not seeing completion handler/progress block kicking in.

While looking at this it appeared as if AWS doesn't really track the data associated with the task and looks like have to maintain and upload the data manually.

Any idea how to handle the retry?


Solution

  • By default, the retry limit seems to be 0. It can be changed by setting

    AWSS3TransferUtilityConfiguration().retryLimit = ...
    

    resume() is not applicable in this case.