-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory leak when using @ClientObjectMapper with QuarkusRestClientBuilder #44180
Comments
/cc @cescoffier (rest-client) |
+100 |
Sure ! Sorry, I thought I added the version. I'm using 3.15.1. I added a reproducer :) |
Currently, this is used to cleanup up the mappings that is needed to support ClientObjectMapper. The SPI is invoked when the `close` method of a REST Client is called. Resolves: quarkusio#44180
@jbgomond would you be able to try #44212 ? In addition to that PR, you would also neeed to change your code to: @GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
var client = QuarkusRestClientBuilder.newBuilder()
.baseUri(URI.create("https://jsonplaceholder.typicode.com"))
.build(JsonPlaceholderApi.class);
client.getFakeJson();
if (client instanceof Closeable c) {
try {
c.close();
} catch (IOException e) {
Log.debug("Unable to close client", e);
}
}
return "Rest client executed. Check contextResolverMap in JacksonUtil";
} |
That being said, it doesn't look like a good idea to initialize a new REST Client for each call. |
Yeah, it's pretty heavy, but there could be some circumstances where you have no other way. That said, @jbgomond why exactly do you need to create a new instance for every request? |
One of the reasons that used to be necessary in the past, is no longer necessary since |
Initializing a rest client on every call also initialized a connection pool... It can lead to many issues if you have a lot of clients created in parallel. Also, it would not apply the "per-host" limit, which may harm the remote service too. |
Hello ! Sorry for the delay, thanks for the quick fix :) @geoand I must be missing something while testing, I compiled all the maven models using your quarkus branch locally, used the 999-SNAPSHOT in my project but it's not using the RestClientClosingTask class for some reason ? Did I forget something ? @gsmet @cescoffier I agree, I'm planning on adding some sort of cache on my side to avoid over instantiating the builder. The addition in #43331 is very good but in my case, I need to use conditionally a proxy depending on the url called (both provided via a database). |
If you checked out my branch and built Quarkus like so, you should be able to see that class (which you won't have to interact with however)
Mind providing some pseudo-code of what you are doing? I want to see if we can cover this without having to resort to creating a new client |
Yeah I was not awake, I forgot the close() part in my code :D Works fine ! In my case, I have a list of providers in a database. Each line having the url to call and a boolean if I need to use a proxy of not (because all urls are not needing a proxy). So I'm doing that : @GET
@Produces(MediaType.TEXT_PLAIN)
public String callProvider(Provider provider) {
var client = QuarkusRestClientBuilder.newBuilder()
.baseUri(URI.create(provider.getUrl()))
.build(JsonPlaceholderApi.class);
if (provider.getUseProxy() {
// set proxy
}
client.getFakeJson();
if (client instanceof Closeable c) {
try {
c.close();
} catch (IOException e) {
Log.debug("Unable to close client", e);
}
}
return "Rest client executed. Check contextResolverMap in JacksonUtil";
} |
Glad to hear it! What exactly does if (provider.getUseProxy() {
// set proxy
} do with the client? Does it really need a new instance? |
Currently, this is used to cleanup up the mappings that is needed to support ClientObjectMapper. The SPI is invoked when the `close` method of a REST Client is called. Resolves: quarkusio#44180
Describe the bug
Hello !
I needed to customize the
ObjectMapper
used by Quarkus Rest Client. To do that, I created a@ClientObjectMapper
method in the interface as indicated.The interface is then used with QuarkusRestClientBuilder to create rest client instances dynamically (I need to change some parameters depending on the request).
But when coupling both, the objectMapper method gets triggered every time. The Jackson instance is being stored in the
contextResolverMap
variable of the classJacksonUtil
, and is not removed when the rest client is destroyed.And so :
Thanks
Expected behavior
The ObjectMapper is instantiated once or is destroyed with the rest client
Actual behavior
All ObjectMapper instances are kept in memory
How to Reproduce?
github-issue-44180-reproducer.zip
Output of
uname -a
orver
No response
Output of
java -version
21.0.5
Quarkus version or git rev
3.15.1
Build tool (ie. output of
mvnw --version
orgradlew --version
)No response
Additional information
No response
The text was updated successfully, but these errors were encountered: