https://kotlinlang.org logo
#ktor
Title
# ktor
v

Venkat

01/24/2023, 9:12 AM
I have a custom retry policy on receiving 5XX errors from the server. The idea is to retry until I get a non-5XX error with an exponential delay between each retry request also I would like to update the request body on every retry. Here is my code
Copy code
import io.ktor.client.*
    import io.ktor.client.engine.java.*
    import io.ktor.client.plugins.*
    import io.ktor.client.request.*
    import io.ktor.http.*
    import io.ktor.server.application.*
    import io.ktor.server.engine.*
    import io.ktor.server.netty.*
    import io.ktor.server.request.*
    import io.ktor.server.routing.*
    import kotlinx.coroutines.*
    import kotlin.time.Duration.Companion.seconds
    
    suspend fun main() {
        val serverJob = CoroutineScope(Dispatchers.Default).launch { startServer() }
    
        val client = HttpClient(Java) {
            install(HttpTimeout) {
                connectTimeoutMillis = 5.seconds.inWholeMilliseconds
            }
            install(HttpRequestRetry)
        }
    
        <http://client.post|client.post> {
            url("<http://127.0.0.1:8080/>")
            setBody("Hello")
            retry {
                retryOnServerErrors(maxRetries = Int.MAX_VALUE)
                exponentialDelay(maxDelayMs = 128.seconds.inWholeMilliseconds)
                modifyRequest { it.setBody("With Different body ...") } // It's not working! if I comment this out then my retry logic works as expected
            }
        }
    
        client.close()
        serverJob.cancelAndJoin()
    }
    
    suspend fun startServer() {
        embeddedServer(Netty, port = 8080) {
            routing {
                post("/") {
                    val text = call.receiveText()
                    println("Retrying exponentially... $text")
                    call.response.status(HttpStatusCode(500, "internal server error"))
                }
            }
        }.start(wait = true)
    }
As you can see, if I comment out
modifyRequest { it.setBody("With Different body ...") }
line from retry logic then everything works fine. If I include that line it only tries once and stuck there, what I'm doing wrong here? how to change the request body for every retry?
a

Aleksei Tirman [JB]

01/24/2023, 10:11 AM
v

Venkat

01/24/2023, 10:15 AM
Oh! it works thank you so much! One more question, is it ok set content types as
ContentType.Application.Json
instead of plain text?
a

Aleksei Tirman [JB]

01/24/2023, 10:16 AM
Of course, whatever you need.
🤎 1
v

Venkat

01/24/2023, 10:16 AM
Accepted your answer in SO
is there any way to call suspend function inside
modifyRequest
? currently, I can do that via
runBlocking{ f() }
but I wonder if there is any coroutine way of doing it without blocking the thread.
4 Views