Extract caching from participant-state as a library (#5949)

* Extract caching from participant-state as a library

This will be used to keep a cache of values to cut on LF translation cost when serving transactions.

changelog_begin
changelog_end

* Add dependency where missing
This commit is contained in:
Stefano Baghino 2020-05-12 19:45:55 +02:00 committed by GitHub
parent 0ec0cc335f
commit 9ff36a13cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 100 additions and 63 deletions

View File

@ -28,6 +28,7 @@ da_scala_library(
"//ledger/metrics",
"//ledger/participant-state",
"//ledger/participant-state/kvutils",
"//libs-scala/caching",
"//libs-scala/resources",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:com_typesafe_akka_akka_actor_2_12",
@ -57,6 +58,7 @@ da_scala_test(
"//ledger/participant-state",
"//ledger/participant-state/kvutils",
"//ledger/participant-state/kvutils:kvutils-tests-lib",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/resources",
"@maven//:com_typesafe_akka_akka_actor_2_12",
@ -84,6 +86,7 @@ da_scala_library(
"//ledger/participant-state/kvutils",
"//ledger/participant-state/kvutils/app",
"//ledger/sandbox",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/ports",
"//libs-scala/resources",

View File

@ -12,7 +12,8 @@ import com.daml.ledger.participant.state.kvutils.app.{
ParticipantConfig,
Runner
}
import com.daml.ledger.participant.state.kvutils.caching
import com.daml.caching
import com.daml.ledger.participant.state.kvutils.caching._
import com.daml.lf.engine.Engine
import com.daml.logging.LoggingContext
import com.daml.platform.akkastreams.dispatcher.Dispatcher

View File

@ -9,12 +9,12 @@ import akka.NotUsed
import akka.stream.Materializer
import akka.stream.scaladsl.Source
import com.daml.api.util.TimeProvider
import com.daml.caching.Cache
import com.daml.ledger.api.health.{HealthStatus, Healthy}
import com.daml.ledger.on.memory.InMemoryLedgerReaderWriter._
import com.daml.ledger.on.memory.InMemoryState.MutableLog
import com.daml.ledger.participant.state.kvutils.DamlKvutils.DamlStateValue
import com.daml.ledger.participant.state.kvutils.api.{LedgerReader, LedgerRecord, LedgerWriter}
import com.daml.ledger.participant.state.kvutils.caching.Cache
import com.daml.ledger.participant.state.kvutils.{Bytes, KVOffset, SequentialLogEntryId}
import com.daml.ledger.participant.state.v1._
import com.daml.ledger.validator.LedgerStateOperations.{Key, Value}

View File

@ -97,6 +97,7 @@ da_scala_library(
"//ledger/metrics",
"//ledger/participant-state",
"//ledger/participant-state/kvutils",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/resources",
"@maven//:com_google_protobuf_protobuf_java",
@ -128,6 +129,7 @@ da_scala_library(
"//ledger/participant-state/kvutils",
"//ledger/participant-state/kvutils/app",
"//ledger/sandbox",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/ports",
"//libs-scala/resources",
@ -169,6 +171,7 @@ da_scala_library(
"//ledger/participant-state/kvutils:kvutils-tests-lib",
"//ledger/participant-state/kvutils/app",
"//ledger/sandbox",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/ports",
"//libs-scala/postgresql-testing",

View File

@ -6,6 +6,7 @@ package com.daml.ledger.on.sql
import java.time.Duration
import akka.stream.Materializer
import com.daml.caching
import com.daml.ledger.participant.state.kvutils.api.KeyValueParticipantState
import com.daml.ledger.participant.state.kvutils.app.{
Config,
@ -13,7 +14,7 @@ import com.daml.ledger.participant.state.kvutils.app.{
ParticipantConfig,
ReadWriteService
}
import com.daml.ledger.participant.state.kvutils.caching
import com.daml.ledger.participant.state.kvutils.caching._
import com.daml.ledger.participant.state.v1.SeedService
import com.daml.lf.engine.Engine
import com.daml.logging.LoggingContext

View File

@ -9,13 +9,13 @@ import akka.NotUsed
import akka.stream.Materializer
import akka.stream.scaladsl.Source
import com.daml.api.util.TimeProvider
import com.daml.caching.Cache
import com.daml.ledger.api.domain
import com.daml.ledger.api.health.{HealthStatus, Healthy}
import com.daml.ledger.on.sql.SqlLedgerReaderWriter._
import com.daml.ledger.on.sql.queries.Queries
import com.daml.ledger.participant.state.kvutils.DamlKvutils.{DamlLogEntryId, DamlStateValue}
import com.daml.ledger.participant.state.kvutils.api.{LedgerReader, LedgerRecord, LedgerWriter}
import com.daml.ledger.participant.state.kvutils.caching.Cache
import com.daml.ledger.participant.state.kvutils.{Bytes, KVOffset}
import com.daml.ledger.participant.state.v1._
import com.daml.ledger.validator.LedgerStateOperations.{Key, Value}

View File

@ -41,8 +41,8 @@ da_scala_library(
"//ledger/metrics",
"//ledger/participant-state",
"//ledger/participant-state/protobuf:ledger_configuration_java_proto",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"@maven//:com_github_ben_manes_caffeine_caffeine",
"@maven//:com_google_guava_guava",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:com_typesafe_akka_akka_actor_2_12",
@ -117,6 +117,7 @@ da_scala_test(
"//ledger/metrics",
"//ledger/participant-state",
"//ledger/participant-state/protobuf:ledger_configuration_java_proto",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:com_typesafe_akka_akka_actor_2_12",

View File

@ -37,6 +37,7 @@ da_scala_library(
"//ledger/participant-state-metrics",
"//ledger/participant-state/kvutils",
"//ledger/sandbox",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/ports",
"//libs-scala/resources",

View File

@ -7,8 +7,8 @@ import java.io.File
import java.nio.file.Path
import java.time.Duration
import com.daml.caching
import com.daml.ledger.api.tls.TlsConfiguration
import com.daml.ledger.participant.state.kvutils.caching
import com.daml.ledger.participant.state.v1.ParticipantId
import com.daml.ledger.participant.state.v1.SeedService.Seeding
import com.daml.platform.configuration.Readers._

View File

@ -1,38 +0,0 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.ledger.participant.state.kvutils.caching
import com.daml.ledger.participant.state.kvutils.Bytes
import com.github.benmanes.caffeine.{cache => caffeine}
import com.google.protobuf.MessageLite
trait Weight[-T] {
def weigh(value: T): Size
}
object Weight {
def apply[T](implicit weight: Weight[T]): Weight[T] =
weight
def weigh[T](value: T)(implicit weight: Weight[T]): Size =
weight.weigh(value)
def weigher[Key: Weight, Value: Weight]: caffeine.Weigher[Key, Value] =
new WeightWeigher[Key, Value]
implicit object `Bytes Weight` extends Weight[Bytes] {
override def weigh(value: Bytes): Size =
value.size().toLong
}
implicit object `Message Weight` extends Weight[MessageLite] {
override def weigh(value: MessageLite): Size =
value.getSerializedSize.toLong
}
class WeightWeigher[Key: Weight, Value: Weight] extends caffeine.Weigher[Key, Value] {
override def weigh(key: Key, value: Value): Int =
(Weight.weigh(key) + Weight.weigh(value)).toInt
}
}

View File

@ -3,8 +3,19 @@
package com.daml.ledger.participant.state.kvutils
import com.google.protobuf.MessageLite
import com.daml.caching.{Cache, Weight}
package object caching {
type Size = Long
implicit object `Bytes Weight` extends Weight[Bytes] {
override def weigh(value: Bytes): Cache.Size =
value.size().toLong
}
implicit object `Message Weight` extends Weight[MessageLite] {
override def weigh(value: MessageLite): Cache.Size =
value.getSerializedSize.toLong
}
}

View File

@ -7,9 +7,9 @@ import java.util.UUID
import java.util.concurrent.atomic.AtomicBoolean
import com.codahale.metrics.Timer
import com.daml.caching.Cache
import com.daml.ledger.participant.state.kvutils.DamlKvutils._
import com.daml.ledger.participant.state.kvutils.api.LedgerReader
import com.daml.ledger.participant.state.kvutils.caching.Cache
import com.daml.ledger.participant.state.kvutils.{Bytes, Envelope, KeyValueCommitting}
import com.daml.ledger.participant.state.v1.ParticipantId
import com.daml.ledger.validator.SubmissionValidator._

View File

@ -6,9 +6,9 @@ package com.daml.ledger.validator
import java.time.Clock
import com.codahale.metrics.MetricRegistry
import com.daml.caching.Cache
import com.daml.ledger.participant.state.kvutils.DamlKvutils._
import com.daml.ledger.participant.state.kvutils.MockitoHelpers.captor
import com.daml.ledger.participant.state.kvutils.caching.Cache
import com.daml.ledger.participant.state.kvutils.{Bytes, Envelope, KeyValueCommitting}
import com.daml.ledger.participant.state.v1.ParticipantId
import com.daml.ledger.validator.SubmissionValidator.{LogEntryAndState, RawKeyValuePairs}

View File

@ -29,6 +29,7 @@ da_scala_test_suite(
"//ledger/participant-state/kvutils",
"//ledger/sandbox:ledger-api-server",
"//ledger/test-common",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/resources",
"//libs-scala/resources-akka",

View File

@ -38,6 +38,7 @@ compile_deps = [
"//ledger/participant-state-metrics",
"//ledger/participant-state/kvutils",
"//libs-scala/build-info",
"//libs-scala/caching",
"//libs-scala/contextualized-logging",
"//libs-scala/direct-execution-context",
"//libs-scala/ports",

View File

@ -12,13 +12,14 @@ import akka.stream.Materializer
import akka.stream.scaladsl.Sink
import com.daml.api.util.TimeProvider
import com.daml.buildinfo.BuildInfo
import com.daml.caching
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger.api.auth.{AuthServiceWildcard, Authorizer}
import com.daml.ledger.api.domain
import com.daml.ledger.on.sql.Database.InvalidDatabaseException
import com.daml.ledger.on.sql.SqlLedgerReaderWriter
import com.daml.ledger.participant.state.kvutils.api.KeyValueParticipantState
import com.daml.ledger.participant.state.kvutils.caching
import com.daml.ledger.participant.state.kvutils.caching._
import com.daml.ledger.participant.state.v1
import com.daml.ledger.participant.state.v1.metrics.{TimedReadService, TimedWriteService}
import com.daml.ledger.participant.state.v1.{SeedService, WritePackagesService}
@ -260,5 +261,5 @@ object Runner {
private val InMemoryIndexJdbcUrl =
"jdbc:h2:mem:index;db_close_delay=-1;db_close_on_exit=false"
private val MaximumStateValueCacheSize: caching.Size = 128L * 1024 * 1024
private val MaximumStateValueCacheSize: caching.Cache.Size = 128L * 1024 * 1024
}

View File

@ -0,0 +1,20 @@
# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
load(
"//bazel_tools:scala.bzl",
"da_scala_library",
)
da_scala_library(
name = "caching",
srcs = glob(["src/main/scala/**/*.scala"]),
tags = ["maven_coordinates=com.daml:caching:__VERSION__"],
visibility = [
"//:__subpackages__",
],
deps = [
"@maven//:com_github_ben_manes_caffeine_caffeine",
"@maven//:org_scala_lang_modules_scala_java8_compat_2_12",
],
)

View File

@ -1,25 +1,28 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.ledger.participant.state.kvutils.caching
package com.daml.caching
import com.github.benmanes.caffeine.{cache => caffeine}
import scala.compat.java8.OptionConverters._
trait Cache[Key, Value] {
sealed abstract class Cache[Key, Value] {
def get(key: Key, acquire: Key => Value): Value
def size: Size
def size: Cache.Size
def weight: Size
def weight: Cache.Size
}
object Cache {
type Size = Long
def none[Key, Value]: Cache[Key, Value] = new NoCache
def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration
configuration: Configuration,
): Cache[Key, Value] =
configuration match {
case Configuration(0) =>
@ -33,23 +36,23 @@ object Cache {
.build[Key, Value]())
}
final class NoCache[Key, Value] extends Cache[Key, Value] {
final class NoCache[Key, Value] private[Cache] extends Cache[Key, Value] {
override def get(key: Key, acquire: Key => Value): Value = acquire(key)
override val size: Size = 0
override val size: Cache.Size = 0
override val weight: Size = 0
override val weight: Cache.Size = 0
}
final class CaffeineCache[Key, Value](val cache: caffeine.Cache[Key, Value])
final class CaffeineCache[Key, Value] private[Cache] (val cache: caffeine.Cache[Key, Value])
extends Cache[Key, Value] {
override def get(key: Key, acquire: Key => Value): Value =
cache.get(key, key => acquire(key))
override def size: Size =
override def size: Cache.Size =
cache.estimatedSize()
override def weight: Size =
override def weight: Cache.Size =
cache.policy().eviction().asScala.flatMap(_.weightedSize().asScala).getOrElse(0)
}

View File

@ -1,10 +1,10 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.ledger.participant.state.kvutils.caching
package com.daml.caching
case class Configuration(maximumWeight: Size)
final case class Configuration(maximumWeight: Long) extends AnyVal
object Configuration {
def none: Configuration = Configuration(maximumWeight = 0)
val none: Configuration = Configuration(maximumWeight = 0)
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import com.github.benmanes.caffeine.{cache => caffeine}
trait Weight[-T] {
def weigh(value: T): Cache.Size
}
object Weight {
def apply[T](implicit weight: Weight[T]): Weight[T] =
weight
def weigh[T](value: T)(implicit weight: Weight[T]): Cache.Size =
weight.weigh(value)
def weigher[Key: Weight, Value: Weight]: caffeine.Weigher[Key, Value] =
new WeightWeigher[Key, Value]
final class WeightWeigher[Key: Weight, Value: Weight] extends caffeine.Weigher[Key, Value] {
override def weigh(key: Key, value: Value): Int =
(Weight.weigh(key) + Weight.weigh(value)).toInt
}
}

View File

@ -128,6 +128,8 @@
type: jar-scala
- target: //libs-scala/auth-utils:auth-utils
type: jar-scala
- target: //libs-scala/caching:caching
type: jar-scala
- target: //libs-scala/contextualized-logging:contextualized-logging
type: jar-scala
- target: //libs-scala/direct-execution-context:direct-execution-context