diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt index 1111e9faf9..6afd7dc4a6 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt @@ -60,7 +60,6 @@ interface NodeConfiguration : ConfigurationWithOptionsContainer { val noLocalShell: Boolean get() = false val transactionCacheSizeBytes: Long get() = defaultTransactionCacheSize val attachmentContentCacheSizeBytes: Long get() = defaultAttachmentContentCacheSize - val attachmentCacheBound: Long get() = defaultAttachmentCacheBound // do not change this value without syncing it with ScheduledFlowsDrainingModeTest val drainingModePollPeriod: Duration get() = Duration.ofSeconds(5) val extraNetworkMapKeys: List<UUID> @@ -110,7 +109,6 @@ interface NodeConfiguration : ConfigurationWithOptionsContainer { } internal val defaultAttachmentContentCacheSize: Long = 10.MB - internal const val defaultAttachmentCacheBound = 1024L const val cordappDirectoriesKey = "cordappDirectories" diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfigurationImpl.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfigurationImpl.kt index 44b77a8264..49390958bf 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfigurationImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfigurationImpl.kt @@ -65,7 +65,6 @@ data class NodeConfigurationImpl( override val database: DatabaseConfig = Defaults.database(devMode), private val transactionCacheSizeMegaBytes: Int? = Defaults.transactionCacheSizeMegaBytes, private val attachmentContentCacheSizeMegaBytes: Int? = Defaults.attachmentContentCacheSizeMegaBytes, - override val attachmentCacheBound: Long = Defaults.attachmentCacheBound, override val extraNetworkMapKeys: List<UUID> = Defaults.extraNetworkMapKeys, // do not use or remove (breaks DemoBench together with rejection of unknown configuration keys during parsing) private val h2port: Int? = Defaults.h2port, @@ -112,7 +111,6 @@ data class NodeConfigurationImpl( const val localShellUnsafe: Boolean = false val transactionCacheSizeMegaBytes: Int? = null val attachmentContentCacheSizeMegaBytes: Int? = null - const val attachmentCacheBound: Long = NodeConfiguration.defaultAttachmentCacheBound val extraNetworkMapKeys: List<UUID> = emptyList() val h2port: Int? = null val h2Settings: NodeH2Settings? = null diff --git a/node/src/main/kotlin/net/corda/node/services/config/schema/v1/V1NodeConfigurationSpec.kt b/node/src/main/kotlin/net/corda/node/services/config/schema/v1/V1NodeConfigurationSpec.kt index ab1f36f417..3808597620 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/schema/v1/V1NodeConfigurationSpec.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/schema/v1/V1NodeConfigurationSpec.kt @@ -40,7 +40,6 @@ internal object V1NodeConfigurationSpec : Configuration.Specification<NodeConfig private val localShellUnsafe by boolean().optional().withDefaultValue(Defaults.localShellUnsafe) private val database by nested(DatabaseConfigSpec).optional() private val noLocalShell by boolean().optional().withDefaultValue(Defaults.noLocalShell) - private val attachmentCacheBound by long().optional().withDefaultValue(Defaults.attachmentCacheBound) private val extraNetworkMapKeys by string().mapValid(::toUUID).list().optional().withDefaultValue(Defaults.extraNetworkMapKeys) private val tlsCertCrlDistPoint by string().mapValid(::toURL).optional() private val tlsCertCrlIssuer by string().mapValid(::toPrincipal).optional() @@ -118,7 +117,6 @@ internal object V1NodeConfigurationSpec : Configuration.Specification<NodeConfig localShellUnsafe = config[localShellUnsafe], database = database, noLocalShell = config[noLocalShell], - attachmentCacheBound = config[attachmentCacheBound], extraNetworkMapKeys = config[extraNetworkMapKeys], tlsCertCrlDistPoint = config[tlsCertCrlDistPoint], tlsCertCrlIssuer = config[tlsCertCrlIssuer], diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt index dbf36b9bae..9937f51a28 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt @@ -26,7 +26,6 @@ import net.corda.core.serialization.* import net.corda.core.utilities.contextLogger import net.corda.node.services.vault.HibernateAttachmentQueryCriteriaParser import net.corda.node.utilities.InfrequentlyMutatedCache -import net.corda.node.utilities.NonInvalidatingCache import net.corda.node.utilities.NonInvalidatingWeightBasedCache import net.corda.nodeapi.exceptions.DuplicateAttachmentException import net.corda.nodeapi.internal.persistence.CordaPersistence @@ -259,18 +258,6 @@ class NodeAttachmentService @JvmOverloads constructor( Token(id, checkOnLoad, uploader, signerKeys) } - // slightly complex 2 level approach to attachment caching: - // On the first level we cache attachment contents loaded from the DB by their key. This is a weight based - // cache (we don't want to waste too much memory on this) and could be evicted quite aggressively. If we fail - // to load an attachment from the db, the loader will insert a non present optional - we invalidate this - // immediately as we definitely want to retry whether the attachment was just delayed. - // On the second level, we cache Attachment implementations that use the first cache to load their content - // when required. As these are fairly small, we can cache quite a lot of them, this will make checking - // repeatedly whether an attachment exists fairly cheap. Here as well, we evict non-existent entries immediately - // to force a recheck if required. - // If repeatedly looking for non-existing attachments becomes a performance issue, this is either indicating a - // a problem somewhere else or this needs to be revisited. - private val attachmentContentCache = NonInvalidatingWeightBasedCache( cacheFactory = cacheFactory, name = "NodeAttachmentService_attachmentContent", @@ -309,27 +296,13 @@ class NodeAttachmentService @JvmOverloads constructor( } } - private val attachmentCache = NonInvalidatingCache<SecureHash, Optional<Attachment>>( - cacheFactory = cacheFactory, - name = "NodeAttachmentService_attachmentPresence", - loadFunction = { key -> Optional.ofNullable(createAttachment(key)) }) - - private fun createAttachment(key: SecureHash): Attachment? { - val content = attachmentContentCache.get(key)!! + override fun openAttachment(id: SecureHash): Attachment? { + val content = attachmentContentCache.get(id)!! if (content.isPresent) { return content.get().first } // If no attachment has been found, we don't want to cache that - it might arrive later. - attachmentContentCache.invalidate(key) - return null - } - - override fun openAttachment(id: SecureHash): Attachment? { - val attachment = attachmentCache.get(id)!! - if (attachment.isPresent) { - return attachment.get() - } - attachmentCache.invalidate(id) + attachmentContentCache.invalidate(id) return null } @@ -426,7 +399,6 @@ class NodeAttachmentService @JvmOverloads constructor( loadAttachmentContent(id)?.let { attachmentAndContent -> // TODO: this is racey. ENT-2870 attachmentContentCache.put(id, Optional.of(attachmentAndContent)) - attachmentCache.put(id, Optional.of(attachmentAndContent.first)) } return@withContractsInJar id } diff --git a/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt b/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt index 3bf2bb08cf..e43b2ab7ee 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/NodeNamedCache.kt @@ -43,7 +43,6 @@ open class DefaultNamedCacheFactory protected constructor(private val metricRegi name == "HibernateConfiguration_sessionFactories" -> caffeine.maximumSize(database.mappedSchemaCacheSize) name == "DBTransactionStorage_transactions" -> caffeine.maximumWeight(transactionCacheSizeBytes) name == "NodeAttachmentService_attachmentContent" -> caffeine.maximumWeight(attachmentContentCacheSizeBytes) - name == "NodeAttachmentService_attachmentPresence" -> caffeine.maximumSize(attachmentCacheBound) name == "NodeAttachmentService_contractAttachmentVersions" -> caffeine.maximumSize(defaultCacheSize) name == "PersistentIdentityService_keyToPartyAndCert" -> caffeine.maximumSize(defaultCacheSize) name == "PersistentIdentityService_nameToParty" -> caffeine.maximumSize(defaultCacheSize)