Skip to content
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

Lingua's use of Kotlin coroutines causes leaks in web applications #110

Closed
dnb-erik-brangs opened this issue Jul 8, 2021 · 10 comments
Closed
Labels
bug Something isn't working
Milestone

Comments

@dnb-erik-brangs
Copy link

I'm using lingua 1.1.0 in a Java web application for language detection. The application is set up to load all models on the first request:

LanguageDetectorBuilder.fromAllLanguages().withPreloadedLanguageModels().build();

When I undeploy the web application from the application server, the models stay in memory. I took a heap dump using Eclipse Memory Anaylzer. The dump shows that there are still instances of the classes related to coroutines (e.g. kotlinx.coroutines.scheduling.CoroutineScheduler$WorkerState, kotlinx.coroutines.scheduling.WorkQueue, kotlinx.coroutines.scheduling.CoroutineScheduler) after undeploying the application. The coroutines still seem to reference the models.

I've built a reproducer using only Servlet API that seems to show similar behaviour on Tomcat. Tomcat shows warnings like this:

WARNUNG: The web application [lingua-reproducer] appears to have started a thread named [DefaultDispatcher-worker-9] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.park(CoroutineScheduler.kt:795)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.tryPark(CoroutineScheduler.kt:740)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:711)
kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

Is there are way to ensure that the threads created by Lingua terminate when the application is undeployed?

@pemistahl
Copy link
Owner

Hello Erik, thanks for your request.

I'm not exactly sure but after doing some investigation, this seems to be a bug in Kotlin coroutines version 1.4. Version 1.5 has been released already, so updating the dependency will probably fix this issue. I will update all dependencies for the next version of Lingua but I cannot tell you at the moment when I will publish a new release.

@dnb-erik-brangs
Copy link
Author

Thank you.

I'd be willing to test a SNAPSHOT version for the next release when the bug is fixed on the main branch.

@pemistahl
Copy link
Owner

Hi Erik, you can now clone this repository, switch to branch v1.2.0-wip and execute ./gradlew jarWithDependencies. You can then use the resulting jar file lingua-1.2.0-SNAPSHOT-with-dependencies.jar in your project to test whether the coroutine bug is gone with the updated dependency.

I close this issue here because this is not a bug in Lingua.

@dnb-erik-brangs
Copy link
Author

Thank you.

I've tested the new version and the problem is still present.

Our applications are normally designed so that we can manually cancel outstanding tasks (e.g. java.util.concurrent.Future from ExecutorService) when the application is shut down. Is there a way to get access to Lingua's task classes so that the application can manually shut them down on undeploy?

@pemistahl
Copy link
Owner

I've just found out that there is a way to manually cancel coroutine execution. I will have to try this out:
https://kotlinlang.org/docs/cancellation-and-timeouts.html

Perhaps it makes sense for you to ask the coroutine devs directly as they surely know more about how to handle this than I do. Please let me know as soon as you find out anything new.

In the meantime, I'm going to re-open this issue again. There is obviously still something to do in my code.

@pemistahl pemistahl reopened this Jul 22, 2021
@pemistahl pemistahl added the bug Something isn't working label Jul 22, 2021
@pemistahl pemistahl added this to the Lingua 1.2.0 milestone Jul 22, 2021
@dnb-erik-brangs
Copy link
Author

I'm not at all familiar with Kotlin coroutines but from skimming the documentation, it sounds like CoroutineScope might be helpful ( https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html#coroutine-scope ).

@pemistahl
Copy link
Owner

@dnb-erik-brangs I'm a bit late, I know, but I have just applied some modifications to the LanguageDetector which might help to resolve the issue. Can you perhaps build the JAR file again on the branch v1.1.1-wip and check whether the issue still exists? Alternatively, can you tell me how exactly I can reproduce the issue myself? Thank you.

@pemistahl
Copy link
Owner

@dnb-erik-brangs I'm closing this issue now so that I can prepare the release 1.1.1. If your problem still exists despite the recent changes, please open a new GitHub issue. Thanks.

@dnb-erik-brangs
Copy link
Author

Thank you.

The problem still seems to exist. I will open a new issue and link a repository with an example application that exhibits the problem.

@pemistahl
Copy link
Owner

That's great. I'm still willing to find a solution to your problem and I'm sure that I will find one with the help of an example application of yours. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants