Example:
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import java.time.Duration
@RestController
class Controller {
@GetMapping
fun test(): String {
Thread.sleep(200)
return "hello world"
}
}
fun main() {
requestWithTimeout(Duration.ofMillis(500)) //no timeout, as expected
requestWithTimeout(Duration.ofMillis(1)) //timeout, as expected
requestWithTimeout(Duration.ofNanos(1_000_000)) //timeout, as expected
requestWithTimeout(Duration.ofNanos(999_999)) //no timeout, but expected
requestWithTimeout(Duration.ZERO)
}
fun requestWithTimeout(duration: Duration) = println("$duration -> ${request(duration)}")
private fun request(duration: Duration): String? {
return try {
RestTemplateBuilder()
.setReadTimeout(duration)
.build()
.getForEntity("http://127.0.0.1:8080", String::class.java)
.body
} catch (e: Exception) {
e.message
}
}
Result:
PT0.5S -> hello world
PT0.001S -> I/O error on GET request for "http://127.0.0.1:8080": Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out
PT0.001S -> I/O error on GET request for "http://127.0.0.1:8080": Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out
PT0.000999999S -> hello world
PT0S -> hello world
I think problem is here: RestTemplateBuilder.setReadTimeout.
Spring Boot version: 2.3.4.RELEASE
Comment From: wilkinsona
Thanks for the report. The read timeout has millisecond precision so I don't think there's anything we can do to change the behaviour here. Furthermore, Duration.ofNanos(999_999).toMillis()
returns 0. What do you expect the millisecond timeout to be when you set it to a value less than a millisecond?
Comment From: Potat0x
Furthermore,
Duration.ofNanos(999_999).toMillis()
returns 0. What do you expect the millisecond timeout to be when you set it to a value less than a millisecond?
Thats why I pasted link to this function :)
Thanks for the report. The read timeout has millisecond precision so I don't think there's anything we can do to change the behaviour here.
You mean precision of underlying libraries?
Comment From: wilkinsona
Thats why I pasted link to this function :)
I had assumed as much, but that doesn't answer my question which was the following:
What do you expect the millisecond timeout to be when you set it to a value less than a millisecond?
You mean precision of underlying libraries?
Yes.
Comment From: Potat0x
I had assumed as much, but that doesn't answer my question which was the following:
What do you expect the millisecond timeout to be when you set it to a value less than a millisecond?
0? But there is also toNanos
. Anyway, it doesnt matter if underlying library use millisecond precision.