diff --git a/build.sbt b/build.sbt index 8307412..14098ad 100644 --- a/build.sbt +++ b/build.sbt @@ -16,6 +16,8 @@ libraryDependencies ++= Seq( "org.apache.tinkerpop" % "tinkergraph-gremlin" % "3.3.0", //TODO: "com.github.mdr" %% "ascii-graphs" % "0.0.3", pending 2.12 "com.indvd00m.ascii.render" % "ascii-render" % "1.2.1", //used instead of above^ + "com.github.cb372" %% "scalacache-core" % "0.22.0", + "com.github.cb372" %% "scalacache-caffeine" % "0.22.0", "org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0", "org.scala-lang" % "scala-reflect" % scalaVersion.value, "org.log4s" %% "log4s" % "1.4.0" diff --git a/src/main/scala/net/mikolak/travesty/Registry.scala b/src/main/scala/net/mikolak/travesty/Registry.scala index ebe2d87..d9188c3 100644 --- a/src/main/scala/net/mikolak/travesty/Registry.scala +++ b/src/main/scala/net/mikolak/travesty/Registry.scala @@ -3,8 +3,25 @@ package net.mikolak.travesty import akka.stream.{Graph, Shape} import scala.reflect.runtime.universe._ +import scalacache.Id object Registry { + import scalacache.Cache + import scalacache.modes.sync._ + import scalacache.caffeine._ + import scala.concurrent.duration._ + import language.postfixOps + + private val cache: Cache[ShapeTypes] = CaffeineCache[ShapeTypes] + + def register[T <: Graph[_ <: Shape, _]: TypeTag](g: T): T = { + val shapeTypes = deconstructShape(g) + cache.put(g)(shapeTypes, ttl = Some(5 minutes)) //TODO: move to config + g + } + + def lookup(g: Graph[_ <: Shape, _]): Id[Option[ShapeTypes]] = cache.get(g) + private[travesty] def deconstructShape[T <: Graph[_ <: Shape, _]: TypeTag](g: T): ShapeTypes = { val tpe = typeOf[T] val graphType = tpe.baseType(typeOf[Graph[_, _]].typeSymbol) diff --git a/src/test/scala/net/mikolak/travesty/RegistrySpec.scala b/src/test/scala/net/mikolak/travesty/RegistrySpec.scala index 9310615..9cbc355 100644 --- a/src/test/scala/net/mikolak/travesty/RegistrySpec.scala +++ b/src/test/scala/net/mikolak/travesty/RegistrySpec.scala @@ -45,6 +45,35 @@ class RegistrySpec extends FlatSpec with MustMatchers with MustVerb with TableDr tested(Flow[A].mapAsync(3)(a => Future.successful(a.toB)).async) must be(ShapeTypes(List(typeOf[A]), List(typeOf[B]))) } } + + { + def when[T <: Graph[_ <: Shape, _]: TypeTag](g: T) = Registry.register(g) + + "register" must "remember shape immediately after saving" in { + val s = Source.single("t") + + when(s) + + Registry.lookup(s) must be a 'nonEmpty + } + + it must "not remember a non-saved shape" in { + val s = Source.single("t") + + Registry.lookup(s) must be an 'empty + } + + it must "remember a shape after a short time" in { + val s = Flow[B].map(identity) + + when(s) + + Thread.sleep(100) + + Registry.lookup(s) must be a 'nonEmpty + } + + } } trait A {