I defined an interface to download a file
@GetMapping("/video.mp4")
public Mono<Void> video(ServerHttpResponse response) {
ZeroCopyHttpOutputMessage zeroCopyResponse = (ZeroCopyHttpOutputMessage) response;
response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=video.mp4");
response.getHeaders().setContentType(MediaType.parseMediaType("video/mpeg4"));
File file = new File("/Users/Shared/video.mp4");
return zeroCopyResponse.writeWith(file, 0, file.length());
}
And I defined a test interface to run http requests
@GetMapping("test")
public Mono<Void> a() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(20);
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 20; i++) {
int index = i;
executorService.execute(() -> {
try {
Request request = new Request.Builder()
.url("http://127.0.0.1:8080/video.mp4")
.build();
Response response = new OkHttpClient().newCall(request).execute();
if (response.code() == 200) {
ResponseBody body = response.body();
if (body == null) {
throw new DownloadException("Body is null");
}
System.out.println("s: " + index);
} else {
System.out.println("f: " + index);
}
} catch (Throwable e) {
System.out.println("e: " + index);
e.printStackTrace();
} finally {
latch.countDown();
}
});
}
latch.await();
return Mono.empty();
}
But I got timeout exception on several of them
I did some tests
Test | Result | Conclusion |
---|---|---|
Use HttpClient instead of OkHttp |
Timeout exception | Http client has no problem |
Do not use CountDownLatch |
Work well | I do not know why |
New Thread instead of ExecutorService |
Timeout exception | ExecutorService has no problem |
Use MVC instead of WebFlux |
Work well | Spring mvc is work well |
MVC (run http interface) request WebFlux (download file interface) |
Timeout exception | The interface to download file has problem |
WebFlux (run http interface) request MVC (download file interface) |
Work well | The interface to download file has problem |
Under the same conditions,use CountDownLatch
makes timeout?
So I doubt
- WebFlux bug
- I write the wrong code to download a file
spring boot version: 2.6.0
Comment From: bclozel
Given your description here, it's hard to understand what's the actual setup (how many applications are there and what's the relationship between them, libraries versions, etc).
I must say that the CountDownLatch
+ blocking client seems odd, as WebClient
with flatMap
+ then
operators will do a much better job there.
In my opinion, looking at the conclusions of your experiments, so far this points to a setup issue on the client side more than a WebFlux bug: each service can work well independently in several scenarios. If the goal is to somehow stress test an existing service, tools like Gatling, JMeter or any other similar tool will do a much better job. You can also independently test your client on a different testing service that serves static files.
I'm closing this issue as there's no evidence of a WebFlux bug. If you need more assistance, feel free to ask on StackOverflow - don't forget to provide more details there (and a link to a sample people can take a look at), as the current description makes it hard to reproduce the behavior you're seeing.