spring-cloud-commons icon indicating copy to clipboard operation
spring-cloud-commons copied to clipboard

Load Balancer RequestInterceptor breaks large file uploads

Open ZIRAKrezovic opened this issue 1 year ago • 2 comments

Describe the bug

This is basically present in anything that implements a ClientRequestInterceptor. See the original bug report for Spring Framework, along with reproducer that uses spring-cloud-starter-loadbalancer and SimpleLoadBalancer.

As it turns out, adding a ClientRequestInterceptor to a RestClient or RestTemplate results in it being wrapped in "Buffering" factory rather than "Streaming" factory, effectively breaking the streaming functionality required for large file upload. This makes usage of load balancer client unsuitable for transferring large files between microservices that communicate via load balancer addresses.

Spring framework developer has responded that they have no plan to fix this or provide a solution, as the ClientRequestInterceptor contract is fixed.

Is there an alternative for spring cloud loadbalancer implementation to implement something other than ClientRequestInterceptor and achieve the same functionality?

https://github.com/spring-projects/spring-framework/issues/32879 https://github.com/ZIRAKrezovic/spring-multipart-reproducer

Sample If possible, please provide a test case or sample application that reproduces the problem. This makes it much easier for us to diagnose the problem and to verify that we have fixed it.

ZIRAKrezovic avatar May 23 '24 14:05 ZIRAKrezovic

@ZIRAKrezovic - yes, it's there; you can use a WebClient instance created with @LoadBalanced WebClient.Builder to achieve this. You can also use it as the base of client for Spring Interface Clients if you do not want to work directly with the reactive API.

OlgaMaciaszek avatar Jun 25 '24 11:06 OlgaMaciaszek

Yes, I personally use web client, but sadly not everybody wants webflux as a dependency in webmvc application.

ZIRAKrezovic avatar Jun 25 '24 11:06 ZIRAKrezovic

Hello @ZIRAKrezovic . We have discussed it as a team and we've decided that implementing another blocking, non-interceptor-based solution is not something we are going to be adding to the backlog at this point. As a workaround, you can work directly with the LoadBalancer bean, for example RoundRobinLoadBalancer to retrieve the instance you want to use, and then, direct your calls there, without using the OOTB @LoadBalanced-annotated beans.

OlgaMaciaszek avatar Sep 06 '24 11:09 OlgaMaciaszek