Hi guys, Ran into a problem with request timeout ...
# ktor
s
Hi guys, Ran into a problem with request timeout with ktor client when downloading big files with slow internet speed. I have these timeouts set:
Copy code
val httpClient = HttpClient(OkHttp) {
    install(HttpTimeout) {
        requestTimeoutMillis = 15000 // 15 seconds
        connectTimeoutMillis = 15000 // 15 seconds
        socketTimeoutMillis = 300000 // 5 minutes
    }
}
The way I receive it is pretty much the same as described in ktor client documentation here:
Copy code
logger.debug("Downloading `$resourcePath` of size $length")

val output = FileOutputStream(fileToUpdate, true)
httpClient.prepareGet(url) {
    header("Authorization", "Bearer $SLAVE_TOKEN")
}.execute { httpResponse ->
    val channel: ByteReadChannel = httpResponse.body()
    while (!channel.isClosedForRead) {
        val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
        while (!packet.isEmpty) {
            val bytes = packet.readBytes()
            output.write(bytes)
        }
    }
}
With big files I get this:
Copy code
[DEBUG] 2023-06-25 17:51:54.678 [DefaultDispatcher-worker-83]: Downloading `clients/techno_magic/mods/netherlicious-3.0.2.jar` of size 98916964
[ERROR] 2023-06-25 17:52:09.799 [DefaultDispatcher-worker-31]: Failed to download `clients/techno_magic/mods/netherlicious-3.0.2.jar`
io.ktor.client.plugins.HttpRequestTimeoutException: Request timeout has expired [url=<http://example.com/api/resource/clients/techno_magic/mods/netherlicious-3.0.2.jar>, request_timeout=15000 ms]
I may be wrong or miss understand something, but shouldn't sequential reading prevent the request timeout? For me it feels like this kind of timeout should come out when a server is not responding at all, but if you are actively receiving bytes, then why is it considered a timeout? In theory, I could slap a huge number and call it a day, but this feels wrong and unreliable. Is there a more appropriate way to solve that? p.s. I have tried "range" requests but with too big blocks they don't solve anything, as a user with 20kb/s speed would still fail to download 1MB block, and with smaller blocks(like 64kb) application is making a whole lot more requests(like +1500 requests for a 100MB file) and for those with good bandwidth will download files for 5 minutes instead of 20 seconds as before.
n
from the documentation: • request timeout — a time period required to process an HTTP call: from sending a request to receiving a response. • connection timeout — a time period in which a client should establish a connection with a server. • socket timeout — a maximum time of inactivity between two data packets when exchanging data with a server. So request timeout is for the whole request from start to finish, that is why after 15 seconds your request gets timedout
a
I confirm that this behavior is expected according to the documentation.
510 Views