From 98598dfc19b1852e5acbea2802fc0fff1c89a7fc Mon Sep 17 00:00:00 2001 From: Diego Date: Sat, 29 Sep 2018 19:58:34 -0300 Subject: ContextHolder --- build.sbt | 4 +- kamon-core-bench/library/kanela-agent-0.0.400.jar | Bin 0 -> 4828138 bytes .../kamon/bench/ThreadLocalStorageBenchmark.scala | 30 +++++++++++--- .../agent/bootstrap/context/ContextHolder.java | 9 ++++ .../main/scala/kamon/context/ContextHolder.scala | 3 ++ .../src/main/scala/kamon/context/Storage.scala | 46 +++++++++++++++++++-- project/build.properties | 2 +- 7 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 kamon-core-bench/library/kanela-agent-0.0.400.jar create mode 100644 kamon-core/src/main/java/kanela/agent/bootstrap/context/ContextHolder.java create mode 100644 kamon-core/src/main/scala/kamon/context/ContextHolder.scala diff --git a/build.sbt b/build.sbt index 4790074f..e323a456 100644 --- a/build.sbt +++ b/build.sbt @@ -20,10 +20,10 @@ lazy val kamon = (project in file(".")) .aggregate(core, testkit, coreTests, coreBench) val commonSettings = Seq( - scalaVersion := "2.12.4", + scalaVersion := "2.12.7", javacOptions += "-XDignore.symbol.file", resolvers += Resolver.mavenLocal, - crossScalaVersions := Seq("2.12.4", "2.11.8", "2.10.6"), + crossScalaVersions := Seq("2.12.7", "2.11.8", "2.10.6"), concurrentRestrictions in Global += Tags.limit(Tags.Test, 1), scalacOptions ++= Seq( "-deprecation", diff --git a/kamon-core-bench/library/kanela-agent-0.0.400.jar b/kamon-core-bench/library/kanela-agent-0.0.400.jar new file mode 100644 index 00000000..9ec36fc7 Binary files /dev/null and b/kamon-core-bench/library/kanela-agent-0.0.400.jar differ diff --git a/kamon-core-bench/src/main/scala/kamon/bench/ThreadLocalStorageBenchmark.scala b/kamon-core-bench/src/main/scala/kamon/bench/ThreadLocalStorageBenchmark.scala index e67a913e..1bd6f4ce 100644 --- a/kamon-core-bench/src/main/scala/kamon/bench/ThreadLocalStorageBenchmark.scala +++ b/kamon-core-bench/src/main/scala/kamon/bench/ThreadLocalStorageBenchmark.scala @@ -22,14 +22,23 @@ import kamon.context.Storage.Scope import kamon.context.{Context, Key, Storage} import org.openjdk.jmh.annotations._ -@State(Scope.Benchmark) +@State(Scope.Thread) class ThreadLocalStorageBenchmark { - val TestKey: Key[Int] = Key.local("test-key", 0) - val ContextWithKey: Context = Context.create().withKey(TestKey, 43) + var TestKey: Key[Int] = _ + var ContextWithKey: Context = _ - val TLS: Storage = new OldThreadLocal - val FTLS: Storage = new Storage.ThreadLocal + var TLS: Storage = _ + var FTLS: Storage = _ + + @Setup + def setup() = { + TestKey = Key.local("test-key", 0) + ContextWithKey = Context.create().withKey(TestKey, 43) + + TLS = new OldThreadLocal + FTLS = Storage.ThreadLocal() + } @Benchmark @@ -53,6 +62,17 @@ class ThreadLocalStorageBenchmark { scope.close() FTLS.current() } + + @Benchmark + @BenchmarkMode(Array(Mode.AverageTime)) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork(jvmArgsAppend = Array("-javaagent:library/kanela-agent-0.0.400.jar")) + def superFastThreadLocal: Context = { + val scope = FTLS.store(ContextWithKey) + FTLS.current() + scope.close() + FTLS.current() + } } diff --git a/kamon-core/src/main/java/kanela/agent/bootstrap/context/ContextHolder.java b/kamon-core/src/main/java/kanela/agent/bootstrap/context/ContextHolder.java new file mode 100644 index 00000000..ae8d41b6 --- /dev/null +++ b/kamon-core/src/main/java/kanela/agent/bootstrap/context/ContextHolder.java @@ -0,0 +1,9 @@ +package kanela.agent.bootstrap.context; + +public final class ContextHolder { + public Object value; + + public ContextHolder(Object value) { + this.value = value; + } +} diff --git a/kamon-core/src/main/scala/kamon/context/ContextHolder.scala b/kamon-core/src/main/scala/kamon/context/ContextHolder.scala new file mode 100644 index 00000000..321d478f --- /dev/null +++ b/kamon-core/src/main/scala/kamon/context/ContextHolder.scala @@ -0,0 +1,3 @@ +//package kanela.agent.bootstrap.context +// +//final class ContextHolder(var value: Object) diff --git a/kamon-core/src/main/scala/kamon/context/Storage.scala b/kamon-core/src/main/scala/kamon/context/Storage.scala index 2b409592..5ead7db9 100644 --- a/kamon-core/src/main/scala/kamon/context/Storage.scala +++ b/kamon-core/src/main/scala/kamon/context/Storage.scala @@ -15,6 +15,10 @@ package kamon.context +import kanela.agent.bootstrap.context.ContextHolder + +//import kanela.agent.bootstrap.context.ContextHolder + trait Storage { def current(): Context def store(context: Context): Storage.Scope @@ -40,7 +44,15 @@ object Storage { *

One small change is that we don't use an kamon-defined holder object as that would prevent class unloading. * * */ - class ThreadLocal extends Storage { + + object ThreadLocal { + def apply(): Storage = { + if(classOf[ContextHolder].getClassLoader == null) SuperFastThreadLocal() + else FastThreadLocal() + } + } + + final class FastThreadLocal extends Storage { private val tls = new java.lang.ThreadLocal[Array[AnyRef]]() { override def initialValue(): Array[AnyRef] = Array(Context.Empty) @@ -61,7 +73,35 @@ object Storage { } } - object ThreadLocal { - def apply(): ThreadLocal = new ThreadLocal() + object FastThreadLocal { + def apply(): FastThreadLocal = new FastThreadLocal() + } + + + final class SuperFastThreadLocal extends Storage { + private val tls = new java.lang.ThreadLocal[ContextHolder]() { + override def initialValue(): ContextHolder = { + new ContextHolder(Context.Empty) + } + } + + override def current(): Context = + tls.get().value.asInstanceOf[Context] + + override def store(newContext: Context): Scope = { + val ref = tls.get() + val previousContext = ref.value + ref.value = newContext + + new Scope { + override def context: Context = newContext + override def close(): Unit = ref.value = previousContext + } + } + } + + object SuperFastThreadLocal { + def apply(): SuperFastThreadLocal = new SuperFastThreadLocal() } } + diff --git a/project/build.properties b/project/build.properties index c091b86c..133a8f19 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.16 +sbt.version=0.13.17 -- cgit v1.2.3