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

Connection leak on execute (Hikari) #11

Open
DeMol-EE opened this issue Jan 16, 2019 · 7 comments
Open

Connection leak on execute (Hikari) #11

DeMol-EE opened this issue Jan 16, 2019 · 7 comments

Comments

@DeMol-EE
Copy link

I'm using rxkotlin-jdbc and a Hikari data source in a TornadoFX project and found that a connection is leaking whenever I use fun DataSource.execute to delete objects from an underlying PostgreSQL database. I came across this by enabling logging with the JVM parameter -Dorg.slf4j.simpleLogger.log.com.zaxxer.hikari=debug and setting the hikari config's leakDetectionThreshold property to 60_000 ms, which showed the following output in my console:

[HikariPool-1 housekeeper] DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Pool stats (total=10, active=0, idle=10, waiting=0)
[HikariPool-1 housekeeper] DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
[HikariPool-1 housekeeper] DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
[HikariPool-1 housekeeper] WARN com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for org.postgresql.jdbc.PgConnection@3fd29f40 on thread tornadofx-thread-2, stack trace follows
java.lang.Exception: Apparent connection leak detected
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)
	at org.nield.rxkotlinjdbc.DatasourceKt$execute$1.invoke(datasource.kt:78)
	at org.nield.rxkotlinjdbc.DatasourceKt$execute$1.invoke(datasource.kt)
	at org.nield.rxkotlinjdbc.PreparedStatementBuilder.toPreparedStatement(PreparedStatementBuilder.kt:80)
	at org.nield.rxkotlinjdbc.UpdateOperation$toSingle$1.call(UpdateOperation.kt:38)
	at org.nield.rxkotlinjdbc.UpdateOperation$toSingle$1.call(UpdateOperation.kt:6)
	at io.reactivex.internal.operators.single.SingleDefer.subscribeActual(SingleDefer.java:36)
	at io.reactivex.Single.subscribe(Single.java:3394)
	at io.reactivex.Single.subscribe(Single.java:3380)
	at <<my tornadofx view class>>$deleteSelected$1.invoke(<<my tornadofx view class>>:157)
	at <<my tornadofx view class>>$deleteSelected$1.invoke(<<my tornadofx view class>>:17)
	at tornadofx.FXTask.call(Async.kt:459)
	at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
o

The specific function in violation:

fun deleteRegistrations(registrations: List<Registration>, idexam: Int) = db.execute(
    "DELETE FROM registered WHERE idexam = ? AND code in (${registrations.joinToString { "?" }});").parameter(
    idexam).parameters(*registrations.map {
    it.code
}.toTypedArray()).toSingle()

jdk: 1.8.0_144
kotlin version: 1.3.10
rxkotlinfx maven version: 2.2.2
hikaricp maven version: 3.2.0

Not sure this is a bug of Hikari or rxkotlin-jdbc, but I found that swapping the execute to insert (and toSingle() to toSingle{true}) fixes the leak. Seems like the connection is not being closed and returned to the pool correctly?

@DeMol-EE
Copy link
Author

In follow up I'd like to add I've discovered another situation in which a connection is leaked, namely on db.execute and db.insert when the query results in a SQLException. I will try to upload a MVC example soon.

@thomasnield
Copy link
Owner

Okay, I'm on vacation but I'll look at it when I get back in a few days. If you can please confirm it's not an issue with Hikari or the MySQL driver and that it is RxKotlin-JDBC that is the source of the issue

@thomasnield
Copy link
Owner

Hmm... yes there is something that doesn't look right here when comparing the implementation of insert() and execute(). The insert() relies on the iterator of toObservable() to close the connection whereas the execute() does nothing with the autoClose argument. I'll take care of this.

https://github.com/thomasnield/rxkotlin-jdbc/blob/master/src/main/kotlin/org/nield/rxkotlinjdbc/UpdateOperation.kt#L37-L39

https://github.com/thomasnield/rxkotlin-jdbc/blob/master/src/main/kotlin/org/nield/rxkotlinjdbc/InsertOperation.kt#L53-L55

@thomasnield
Copy link
Owner

thomasnield commented Feb 12, 2019

@Warkst Alright, I implemented a fix. Can you test a build? You can use JitPack to bring this in as a dependency:
https://jitpack.io/#thomasnield/rxkotlin-jdbc/596332118a

@DeMol-EE
Copy link
Author

Thanks @thomasnield for looking into this. I'm still experiencing connection leaks when something like

    db.execute("some pre-built insert statement").toSingle().blockingGet()

results in an exception.

@sslavian812
Copy link

Hi!
Has this issue been resolved yet?

@utshavtimsina
Copy link

Any updates on this??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants