From ba0ff8f38853305cd68fd6ccc7e86ad41c8bb107 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Tue, 19 Jun 2018 14:07:36 +0200 Subject: [PATCH] Replace Agrona with JCTools as it's Java 7 compatible Signed-off-by: Felix Barnsteiner --- apm-agent-benchmarks/pom.xml | 5 ++++ .../objectpool/ObjectPoolBenchmark.java | 28 +++++++++++++++++-- apm-agent-core/pom.xml | 6 ++-- .../co/elastic/apm/impl/ElasticApmTracer.java | 10 ++++--- .../apm/objectpool/ObjectPoolTest.java | 4 +-- elastic-apm-agent/pom.xml | 4 +-- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/apm-agent-benchmarks/pom.xml b/apm-agent-benchmarks/pom.xml index a985e0c741..c523083677 100644 --- a/apm-agent-benchmarks/pom.xml +++ b/apm-agent-benchmarks/pom.xml @@ -101,6 +101,11 @@ byte-buddy-agent ${version.byte-buddy} + + org.agrona + agrona + 0.9.18 + diff --git a/apm-agent-benchmarks/src/main/java/co/elastic/apm/benchmark/objectpool/ObjectPoolBenchmark.java b/apm-agent-benchmarks/src/main/java/co/elastic/apm/benchmark/objectpool/ObjectPoolBenchmark.java index c1fbbbadc7..636f3e24cb 100644 --- a/apm-agent-benchmarks/src/main/java/co/elastic/apm/benchmark/objectpool/ObjectPoolBenchmark.java +++ b/apm-agent-benchmarks/src/main/java/co/elastic/apm/benchmark/objectpool/ObjectPoolBenchmark.java @@ -25,6 +25,8 @@ import co.elastic.apm.objectpool.impl.QueueBasedObjectPool; import co.elastic.apm.objectpool.impl.ThreadLocalObjectPool; import org.agrona.concurrent.ManyToManyConcurrentArrayQueue; +import org.jctools.queues.MpmcArrayQueue; +import org.jctools.queues.atomic.MpmcAtomicArrayQueue; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -45,6 +47,8 @@ public class ObjectPoolBenchmark extends AbstractBenchmark { private QueueBasedObjectPool agronaQueueObjectPool; private MixedObjectPool mixedObjectPool; private ThreadLocalObjectPool threadLocalObjectPool; + private QueueBasedObjectPool jctoolsQueueObjectPool; + private QueueBasedObjectPool jctoolsAtomicQueueObjectPool; public static void main(String[] args) throws RunnerException { run(ObjectPoolBenchmark.class); @@ -53,6 +57,8 @@ public static void main(String[] args) throws RunnerException { @Setup public void setUp() { blockingQueueObjectPool = new QueueBasedObjectPool<>(new ArrayBlockingQueue<>(256), true, Transaction::new); + jctoolsQueueObjectPool = new QueueBasedObjectPool<>(new MpmcArrayQueue<>(256), true, Transaction::new); + jctoolsAtomicQueueObjectPool = new QueueBasedObjectPool<>(new MpmcAtomicArrayQueue<>(256), true, Transaction::new); agronaQueueObjectPool = new QueueBasedObjectPool<>(new ManyToManyConcurrentArrayQueue<>(256), true, Transaction::new); mixedObjectPool = new MixedObjectPool<>(Transaction::new, new ThreadLocalObjectPool<>(256, true, Transaction::new), @@ -66,7 +72,7 @@ public void tearDown() { System.out.println("Objects created by MixedObjectPool: " + mixedObjectPool.getGarbageCreated()); } - @Benchmark + // @Benchmark @Threads(8) public Transaction testNewOperator() { return new Transaction(); @@ -74,13 +80,29 @@ public Transaction testNewOperator() { @Benchmark @Threads(8) + public Transaction testJctoolsAtomicQueueObjectPool() { + Transaction transaction = jctoolsAtomicQueueObjectPool.createInstance(); + jctoolsAtomicQueueObjectPool.recycle(transaction); + return transaction; + } + + // @Benchmark + @Threads(8) public Transaction testArgonaQueueObjectPool() { Transaction transaction = agronaQueueObjectPool.createInstance(); agronaQueueObjectPool.recycle(transaction); return transaction; } - // @Benchmark + @Benchmark + @Threads(8) + public Transaction testJctoolsQueueObjectPool() { + Transaction transaction = jctoolsQueueObjectPool.createInstance(); + jctoolsQueueObjectPool.recycle(transaction); + return transaction; + } + + //@Benchmark @Threads(8) public Transaction testBlockingQueueObjectPool() { Transaction transaction = blockingQueueObjectPool.createInstance(); @@ -96,7 +118,7 @@ public Transaction testMixedObjectPool() { return transaction; } - @Benchmark + // @Benchmark @Threads(8) public Transaction testThreadLocalObjectPool() { Transaction transaction = threadLocalObjectPool.createInstance(); diff --git a/apm-agent-core/pom.xml b/apm-agent-core/pom.xml index 3d44d26d56..6784cad909 100644 --- a/apm-agent-core/pom.xml +++ b/apm-agent-core/pom.xml @@ -70,9 +70,9 @@ 3.3.7 - org.agrona - agrona - 0.9.18 + org.jctools + jctools-core + 2.1.2 diff --git a/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java b/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java index 81a5143165..12b45c906a 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/impl/ElasticApmTracer.java @@ -35,7 +35,7 @@ import co.elastic.apm.objectpool.impl.QueueBasedObjectPool; import co.elastic.apm.report.Reporter; import co.elastic.apm.report.ReporterConfiguration; -import org.agrona.concurrent.ManyToManyConcurrentArrayQueue; +import org.jctools.queues.atomic.AtomicQueueFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.stagemonitor.configuration.ConfigurationOption; @@ -46,6 +46,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import static org.jctools.queues.spec.ConcurrentQueueSpec.createBoundedMpmc; + /** * This is the tracer implementation which provides access to lower level agent functionality. *

@@ -77,21 +79,21 @@ public class ElasticApmTracer { this.stacktraceConfiguration = configurationRegistry.getConfig(StacktraceConfiguration.class); this.lifecycleListeners = lifecycleListeners; int maxPooledElements = configurationRegistry.getConfig(ReporterConfiguration.class).getMaxQueueSize() * 2; - transactionPool = new QueueBasedObjectPool<>(new ManyToManyConcurrentArrayQueue(maxPooledElements), false, + transactionPool = new QueueBasedObjectPool<>(AtomicQueueFactory.newQueue(createBoundedMpmc(maxPooledElements)),false, new RecyclableObjectFactory() { @Override public Transaction createInstance() { return new Transaction(); } }); - spanPool = new QueueBasedObjectPool(new ManyToManyConcurrentArrayQueue(maxPooledElements), false, + spanPool = new QueueBasedObjectPool<>(AtomicQueueFactory.newQueue(createBoundedMpmc(maxPooledElements)), false, new RecyclableObjectFactory() { @Override public Span createInstance() { return new Span(); } }); - errorPool = new QueueBasedObjectPool<>(new ManyToManyConcurrentArrayQueue(maxPooledElements), false, + errorPool = new QueueBasedObjectPool<>(AtomicQueueFactory.newQueue(createBoundedMpmc(maxPooledElements)), false, new RecyclableObjectFactory() { @Override public ErrorCapture createInstance() { diff --git a/apm-agent-core/src/test/java/co/elastic/apm/objectpool/ObjectPoolTest.java b/apm-agent-core/src/test/java/co/elastic/apm/objectpool/ObjectPoolTest.java index 49d6dae99c..3cc8a16f64 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/objectpool/ObjectPoolTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/objectpool/ObjectPoolTest.java @@ -20,7 +20,7 @@ package co.elastic.apm.objectpool; import co.elastic.apm.objectpool.impl.QueueBasedObjectPool; -import org.agrona.concurrent.ManyToManyConcurrentArrayQueue; +import org.jctools.queues.atomic.MpmcAtomicArrayQueue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -35,7 +35,7 @@ public class ObjectPoolTest { @BeforeEach void setUp() { // objectPool = new ThreadLocalObjectPool<>(10, false, TestRecyclable::new); - objectPool = new QueueBasedObjectPool<>(new ManyToManyConcurrentArrayQueue<>(MAX_SIZE), true, TestRecyclable::new); + objectPool = new QueueBasedObjectPool<>(new MpmcAtomicArrayQueue<>(MAX_SIZE), true, TestRecyclable::new); } @Test diff --git a/elastic-apm-agent/pom.xml b/elastic-apm-agent/pom.xml index 311d5cc045..f837c01b75 100644 --- a/elastic-apm-agent/pom.xml +++ b/elastic-apm-agent/pom.xml @@ -61,8 +61,8 @@ co.elastic.apm.shaded.stagemonitor - org.agrona - co.elastic.apm.shaded.agrona + org.jctools + co.elastic.apm.shaded.jctools