ExpediaGroup / graphql-kotlin

Libraries for running GraphQL in Kotlin

Home Page:https://opensource.expediagroup.com/graphql-kotlin/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

org.apache.http.impl.nio.conn.CPool leak after upgrading 5.4.1 -> 6.5.6

siddheshlatkar opened this issue · comments

We have been using version 5.4.1 for over a year without any problems. However, after updating to version 6.5.6, we have noticed a leak.

One instance of "org.apache.http.impl.nio.conn.CPool" loaded by "org.springframework.boot.loader.LaunchedURLClassLoader @ 0x733200000" occupies 352,023,744 (56.88%) bytes. The memory is accumulated in one instance of "java.util.LinkedList" loaded by "<system class loader>".

Our application makes a call to Elastic Search for every GraphQL request and returns data. After the upgrade, the app works well for about five minutes but then fails to make a call to ES, possibly due to the aforementioned leak. We have determined that the issue arises after upgrading the Expedia library version.

Hello 👋
Based on my brief search it looks like org.apache.http.impl.nio.conn.CPool is part of org.apache.httpcomponents:httpasyncclient library. I don't see this as a dependency of graphql-kotlin-spring-server v6.5.6 (which uses SpringBoot v2.7.2). Double check your project dependencies to see where that dependency is coming from and upgrade it accordingly.

If there is an issue with graphql-kotlin please provide a link to a github repo that reproduces the issue.

For anyone who stumbles upon this:

App was running into this issue because FunctionDataFetcher.runSuspendingFunction is changed to run suspended functions in CoroutineScope. In the previous version, it was running them in GlobalScope.
Our app calls async elastic search apis and uses listeners. In CoroutineScope, coroutines are exiting before closing ES connection.

Hello 👋
CoroutineScope is created per GraphQL request* so all the coroutines are bounded in scope to to the lifecycle of the request. GlobalScope is bounded only to an app lifecycle so it was possible to have runaway coroutines that were still executing even though the request already finished.

If your coroutines are exiting before closing the ES connection it means that you are not correctly managing their scopes and probably should use custom scope to launch your long-lived ES workers.

*you can customize the context through the corresponding factory