mirror of
https://github.com/corda/corda.git
synced 2025-06-13 04:38:19 +00:00
CORDA-2646 - Database connection pools leaking memory on every checkpoint (#4773)
* ENT-3053 Database connection pools leaking memory on every checkpoint. Flip in the thread local from the thread into the fiber. * Back port to OS (needs some gradle changes) and added TODO, ability for it to avoid erroring if not using Hikari. * Review feedback to remove warning.
This commit is contained in:
committed by
Katelyn Baker
parent
96134c8cfa
commit
6c4433d0b5
@ -1,6 +1,9 @@
|
||||
package net.corda.nodeapi.internal.persistence
|
||||
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import com.zaxxer.hikari.pool.HikariPool
|
||||
import com.zaxxer.hikari.util.ConcurrentBag
|
||||
import net.corda.core.internal.NamedCacheFactory
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.core.utilities.contextLogger
|
||||
@ -9,9 +12,10 @@ import rx.Observable
|
||||
import rx.Subscriber
|
||||
import rx.subjects.UnicastSubject
|
||||
import java.io.Closeable
|
||||
import java.lang.reflect.Field
|
||||
import java.sql.Connection
|
||||
import java.sql.SQLException
|
||||
import java.util.UUID
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
@ -254,6 +258,24 @@ class CordaPersistence(
|
||||
// DataSource doesn't implement AutoCloseable so we just have to hope that the implementation does so that we can close it
|
||||
(_dataSource as? AutoCloseable)?.close()
|
||||
}
|
||||
|
||||
val hikariPoolThreadLocal: ThreadLocal<List<Object>>? by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val hikariDataSource = dataSource as? HikariDataSource
|
||||
if (hikariDataSource == null) {
|
||||
null
|
||||
} else {
|
||||
val poolField: Field = HikariDataSource::class.java.getDeclaredField("pool")
|
||||
poolField.isAccessible = true
|
||||
val pool: HikariPool = poolField.get(hikariDataSource) as HikariPool
|
||||
val connectionBagField: Field = HikariPool::class.java.getDeclaredField("connectionBag")
|
||||
connectionBagField.isAccessible = true
|
||||
val connectionBag: ConcurrentBag<ConcurrentBag.IConcurrentBagEntry> = connectionBagField.get(pool) as ConcurrentBag<ConcurrentBag.IConcurrentBagEntry>
|
||||
val threadListField: Field = ConcurrentBag::class.java.getDeclaredField("threadList")
|
||||
threadListField.isAccessible = true
|
||||
val threadList: ThreadLocal<List<Object>> = threadListField.get(connectionBag) as ThreadLocal<List<Object>>
|
||||
threadList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user