opened
jamesceddy
username_0
I am using TransferManager to download files on an unstable connection. It is not unusual to see read timeouts on connections. 

This  issue can be seen with these steps
(1) start N multipart downloads.
(2) use iptables -J DROP to simulate network loss
(3) wait for the outcome from the ProgressListeners

Expected: There is some outcome, once the downloads are completed they should be in any of the terminal states: success/failure/cancel.
Actual: Callbacks to progress listeners are in a non-terminal state (InProgress) in-defiantly.


```
import com.amazonaws.ClientConfiguration
import com.amazonaws.auth.AWSCredentials
import com.amazonaws.auth.AWSCredentialsProvider
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.event.ProgressEventType
import com.amazonaws.event.ProgressListener
import com.amazonaws.retry.PredefinedRetryPolicies
import com.amazonaws.retry.RetryMode
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.amazonaws.services.s3.transfer.Download
import com.amazonaws.services.s3.transfer.TransferManagerBuilder
import java.io.File
import java.util.concurrent.*
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.concurrent.thread


val downloads = mutableMapOf<String, Download>()
val downloadLastCallbackEvents = ConcurrentHashMap<String, ProgressEventType>()
val isNetworkBlockerStarted = AtomicBoolean(false)
val fileKeys = mutableListOf(
    "key/file42mb",
    "key/file22mb",
    "key/file18mb",
    "key/file10mb"
)
fun main() {
    netUp()
    val accessKey = "zzzz"
    val secretKey = "xyz"

    val s3Client = AmazonS3ClientBuilder.standard().withRegion("us-east-1").withCredentials(object :AWSCredentialsProvider{
        override fun getCredentials(): AWSCredentials {
            return BasicAWSCredentials(accessKey, secretKey)
        }

        override fun refresh() {
        }
    }).build()
    ClientConfiguration().withRetryMode(RetryMode.STANDARD).withRetryPolicy(PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(20))
    val transferManager = TransferManagerBuilder.standard()
        .withS3Client(s3Client)
        //.withDisableParallelDownloads(true) // issue is only seen with Parallel enabled
        .withExecutorFactory { Executors.newFixedThreadPool(3) }
        .build()
    println("start")

    fileKeys.forEach{ file ->
        val download = transferManager.download("fried-chicken", file, File(File(file).name))
        downloads[file] = download
        download.addProgressListener(ProgressListener {
            blockNetwork()
            downloadLastCallbackEvents[file] = it.eventType
            println("Progress event $it --> $file")
        })
    }


    while (true){
        println("\n---------------------------------------------------------------------------")
        downloads.forEach{ (key, download) ->
            blockNetwork()
            println(" State is : ${download.state} ==> $key  ==> ${downloadLastCallbackEvents[key]}")
        }
        println("---------------------------------------------------------------------------\n")
        TimeUnit.SECONDS.sleep(5)
    }
}


fun blockNetwork() {
    if (!isNetworkBlockerStarted.getAndSet(true)) {
        thread(start = true) {
            // give some time for transfers to start
            TimeUnit.SECONDS.sleep(1)
            for (i in 1..5){
                netDown(i)
                if (i == 5){
                    println("\n\n\nLAST TIME!\n\n\n")
                    TimeUnit.SECONDS.sleep(6)
                } else {
                    TimeUnit.SECONDS.sleep(40)
                }

                netUp()
                TimeUnit.SECONDS.sleep(2)
            }
            println("----------------------DONE ----------------------------------")
            println("----------------------DONE ----------------------------------")
            println("----------------------DONE ----------------------------------")
        }
        println("STARTED*******************************")
    }
}
fun netUp() {
    println("\n\n\nNETWORK UP!\n\n\n")
    "/usr/bin/sudo -S  /sbin/iptables -D OUTPUT -p tcp --dport 443 -j DROP".runCommand()
}
fun netDown(i:Int){
    println("\n\n\nNETWORK DOWN! $i\n\n\n")
    "/usr/bin/sudo -S  /sbin/iptables -A OUTPUT -p tcp --dport 443 -j DROP".runCommand()
}

fun String.runCommand() {
    ProcessBuilder("/bin/bash", "-c", "echo password| $this")
        .redirectErrorStream(true)
        .redirectOutput(ProcessBuilder.Redirect.INHERIT)
        .redirectError(ProcessBuilder.Redirect.INHERIT)
        .redirectInput(ProcessBuilder.Redirect.INHERIT)
        .start().waitFor()
}

```
TransferManager multipart parellel download failures not forwarded back to the client
issue
created
zoewangg
username_1
Thank you for reporting the issue and submitting the PR! We will take a look shortly
comment
created
zoewangg
username_1
The fix is available in `1.11.750`, closing the issue. Thanks again for reporting the issue and creating the PR!
comment
closed
zoewangg
username_1
issue