diff --git a/node/src/main/kotlin/net/corda/node/utilities/InfrequentlyMutatedCache.kt b/node/src/main/kotlin/net/corda/node/utilities/InfrequentlyMutatedCache.kt index 9f9698164f..4121a92cb9 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/InfrequentlyMutatedCache.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/InfrequentlyMutatedCache.kt @@ -73,7 +73,7 @@ class InfrequentlyMutatedCache(name: String, cacheFactory: Nam backingCache.invalidateAll() } - private fun invalidate(key: K, value: Wrapper.Invalidated): Wrapper.Invalidated { + private fun invalidate(key: K, value: Wrapper.Invalidated): Wrapper.Invalidated? { val tx = contextTransactionOrNull value.invalidators.incrementAndGet() currentlyInvalid[key] = value @@ -81,7 +81,10 @@ class InfrequentlyMutatedCache(name: String, cacheFactory: Nam // When we close, we can't start using caching again until all simultaneously open transactions are closed. tx.onClose { tx.database.onAllOpenTransactionsClosed { decrementInvalidators(key, value) } } } else { - decrementInvalidators(key, value) + if (value.invalidators.decrementAndGet() == 0) { + currentlyInvalid.remove(key) + return null + } } return value } diff --git a/node/src/test/kotlin/net/corda/node/utilities/InfrequentlyMutatedCacheTest.kt b/node/src/test/kotlin/net/corda/node/utilities/InfrequentlyMutatedCacheTest.kt index fab9b1d7be..bfc6a377f6 100644 --- a/node/src/test/kotlin/net/corda/node/utilities/InfrequentlyMutatedCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/utilities/InfrequentlyMutatedCacheTest.kt @@ -25,6 +25,11 @@ class InfrequentlyMutatedCacheTest { database.close() } + @Test(timeout = 300_000) + fun `invalidate outside transaction should not hang`() { + cache.invalidate("Fred") + } + @Test(timeout=300_000) fun `get from empty cache returns result of loader`() { database.transaction {